編碼細節提升

敲代碼過程中,
老是忽略一些小問題,
或者使用過的比較好用的東西后面又記不起來了
所以,單開一貼以作記錄。

### 47、版本號正則表達式
“`
/**
* 匹配版本號 ^\d+(.\d+)+*/      public static boolean isVersionCode(String str) {          return match(str, “^\d+(\.\d+)+ ”);
}

/**
* 正則表達式匹配
*
* @param text 待匹配的文本
* @param reg 正則表達式
* @return
*/
private static boolean match(String text, String reg) {
if (TextUtils.isEmpty(text) || TextUtils.isEmpty(reg)) return false;
return Pattern.compile(reg).matcher(text).matches();
}
“`


46、點擊 彈出EditText的軟件盤

   /**
     *  彈出EditText的軟件盤
     * @param editText
     */
    public static void upEditTextKeyboard(EditText editText) {
        editText.setFocusable(true);
        editText.setFocusableInTouchMode(true);
        editText.requestFocus();
        InputMethodManager inputManager = (InputMethodManager) editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(editText, 0);
    }

45、AS代碼塊快捷鍵

ctrl + alt + t


44、退出應用時關閉java虛擬機

    @Override
    public void onBackPressed() {
         finish();
         System.exit(0);
    }

43、Gradle 的repositories 配置多個URL

allprojects {
    repositories {
        jcenter()
        // Add the Esri public Bintray Maven repository
        maven { url 'https://esri.bintray.com/arcgis' }
        maven { url "https://jitpack.io" }
    }
}

42、viewpager在Scrollview或recycleview中不顯示

viewpager在這些滑動父控件下面使用需要指定高度,才能顯示


41、Parcelable和Serializable的區別

我們知道在Java應用程序當中對類進行序列化操作只需要實現Serializable接口就可以,由系統來完成序列化和反序列化操作,但是在Android中序列化操作有另外一種方式來完成,那就是實現Parcelable接口.也是Android中特有的接口來實現類的序列化操作.原因是Parcelable的性能要強於Serializable.因此在絕大多數的情況下,Android還是推薦使用Parcelable來完成對類的序列化操作的.

首先Parcelable的性能要強於Serializable的原因我需要簡單的闡述一下

1). 在內存的使用中,前者在性能方面要強於後者

2). 後者在序列化操作的時候會產生大量的臨時變量,(原因是使用了反射機制)從而導致GC的頻繁調用,因此在性能上會稍微遜色

3). Parcelable是以Ibinder作爲信息載體的.在內存上的開銷比較小,因此在內存之間進行數據傳遞的時候,Android推薦使用Parcelable,既然是內存方面比價有優勢,那麼自然就要優先選擇.

4). 在讀寫數據的時候,Parcelable是在內存中直接進行讀寫,而Serializable是通過使用IO流的形式將數據讀寫入在硬盤上.

但是:雖然Parcelable的性能要強於Serializable,但是仍然有特殊的情況需要使用Serializable,而不去使用Parcelable,因爲Parcelable無法將數據進行持久化,因此在將數據保存在磁盤的時候,仍然需要使用後者,因爲前者無法很好的將數據進行持久化.(原因是在不同的Android版本當中,Parcelable可能會不同,因此數據的持久化方面仍然是使用Serializable)


40、TextView在代碼中設置img

    /**
     * 設置textView的圖像
     *
     * @param context
     * @param textView
     * @param img
     * @param position--設置圖像位置,left-0, top-1, right-2, bottom-3
     */
    public static void tvSetImg(Context context, TextView textView, int img, int position) {
        Drawable nav_up = context.getResources().getDrawable(img);
        nav_up.setBounds(0, 0, nav_up.getMinimumWidth(), nav_up.getMinimumHeight());
        switch (position) {
            case 0:
                textView.setCompoundDrawables(nav_up, null, null, null);
                break;
            case 1:
                textView.setCompoundDrawables(null, nav_up, null, null);
                break;
            case 2:
                textView.setCompoundDrawables(null, null, nav_up, null);
                break;
            case 3:
                textView.setCompoundDrawables(null, null, null, nav_up);
                break;

        }
    }

39、控件小寫報錯

程序有一個頁面用到了下面的分割線,然後只要是跳轉到這個頁面都會報

Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null objec

這個錯,原因是把View寫成了view,控件大小寫的問題

<?xml version="1.0" encoding="utf-8"?>
<view xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/colorLineGray"
    android:layout_width="match_parent"
    android:layout_height="0.5dp" />
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/colorLineGray"
    android:layout_width="match_parent"
    android:layout_height="0.5dp" />

38、可摺疊的ListView—-ExpandableListView


37、Android中Activity四種啓動模式和taskAffinity屬性詳解

activity的啓動模式會影響Task和Back Stack的狀態,進而影響用戶體驗。除了啓動模式之外,Intent類中定義的一些標誌(以FLAG_ACTIVITY_開頭)也會影響Task和Back Stack的狀態

Android中Activity四種啓動模式和taskAffinity屬性詳解


36、Intent的Action、Category屬性

通過在Action屬性或Category屬性中設置具有一定含義的字符串信息。
然後在項目清單文件中註冊Activity類時,通過標籤來設置與上一步中相同的action或category字符串。從而啓動符合條件的Activity。

android Intent的Action、Category屬性


35、Activity之間的回調

Activity之間不能使用handler進行消息傳遞,所以在不同的Activity之間多用廣播傳遞消息,相鄰的Activity之間可以使用startActivityForResult()進行消息傳遞。

  • A.Activity中的代碼
    注意startActivityForResult()的第二個參數requestCode不能小於0
startActivityForResult(new Intent(A.this,B.class),0);
...
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (resultCode){
            case RESULT_OK:
                new CenterHintToast(A.this,"返回成功!");
                break;
            default:
                break;
        }
    }
  • B.Activity中的代碼
    在finish自身之前setResult()即可
...
 this.setResult(RESULT_OK);
 this.finish();

34、禁止Gradle檢查PNG的合法性

在gradle 中加上

//禁止Gradle檢查PNG的合法性
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false

33、java佔位符的使用

<string name="text1">i am %1$d years old, i am a %2$s</string>

屬性值定義如下:

%n$m[d/f/s] 表示 第n個參數,前面有m個空格(0m表示有m個0,浮點數k.m,表示小數點前保留k位,小數點後保留m位),d爲整數,f爲浮點數,s爲字符串。

具體使用

<string name="gallery_finish">( %1$d / %2$d ) 完成</string>
...
tvFinish.setText(getString(R.string.gallery_finish, resultPhoto.size(), galleryConfig.getMaxSize()));

32、butterknife的導入不能在Module裏面

會報如下錯誤

Could not find method true(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatTextView with id 'textView0'

無法通過反射找到對應的控件

  compile 'com.jakewharton:butterknife:8.5.1'
  annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'

需要把compile放在項目的build.gradle文件中


31、不要在onBindViewHolder方法中調用 notifyDataSetChanged()

會報如下錯誤

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling

如果需要進行刷新操作,可以在onCreateViewHolder方法中進行


30、去掉字符串最後一個字符

str = str.substring(0,str.length()-1)

29、startActivityForResult的使用

相關函數
startActivityForResult(Intent intent, Int requestCode)
onActivityResult(int requestCode, int resultCode, Intent intent)
setResut(int resultCode, Intent intent)

1、startActivityForResult(Intent intent, Int requestCode)

requestCode >=0就好,隨便用於在onActivityResult()區別哪個子模塊回傳的數據,如果還有C.java ,D甚至E子模塊的話,每個區分開不同的requestCode就好。

Intent intent=new Intent();
intent.setClass(A.this, B.class);
startActivityForResult(intent, 0);

2、重寫onActivityResult

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (resultCode) { //resultCode爲回傳的標記,我回傳的是RESULT_OK
            case RESULT_OK:
                Boolean isSubmitOk = data.getBooleanExtra("isSubmitOk",false);
                if (isSubmitOk)finish();
                break;
            default:
                break;
        }
    }

3、目標活動中setResut(int resultCode, Intent intent)
利用intent回傳數據

 setResult(RESULT_OK, new Intent().putExtra("isSubmitOk",true));
 finish();

補充—> 調用setResult()方法必須在finish()之前。
那麼如果在如下方法中調用setResult()也有可能不會返回成功: onPause(), onStop(), onDestroy(),
因爲這些方法調用不一定是在finish之前的,當然在onCreate()就調用setResult肯定是在finish之前的


28、Edittext被遮擋

在清單文件的對應Activity中設置這個屬性

 <activity android:name=".SatisfactionSurveyActivity"
            android:windowSoftInputMode="stateHidden|adjustPan"/>

27、APK內部打開下載鏈接

不用跳轉到瀏覽器下載

  private void updateAPK(String url) {
        if (TextUtils.isEmpty(url)){
            new CenterHintToast(MainActivity.this,"APK路徑出錯!");
            return;
        }
        Uri uri = Uri.parse(HttpMethods.Img_URL+url);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }

26、讓EditText不能自動獲取焦點

在EditText的父級控件中添加如下屬性:

 android:focusable="true"  
 android:focusableInTouchMode="true"

25、RecyclerView檢測是否滑動到底部


24、Android Studio 上SVN的使用

  • 新項目提交到SVN

    VCS—> import into version control —>share into subversion

  • 已經在SVN上的項目更新內容提交到SVN

    Ctrl + K ,AS面板上VCS+向上的箭頭,或者 VCS—>commit changes

  • SVN上項目檢出

    VCS—> checkout from version control —>subversion


23、Android Studio 中建議過濾的文件

  • .idea 文件夾
  • .gradle 文件夾
  • 所有的 build 文件夾
  • 所有的 .iml 文件
  • local.properties 文件

22、使用butterknife 8.*時出現控件無法找到

在butterknife 7.*的時候,只需要引入

compile 'com.jakewharton:butterknife:7.0.0'

但是使用butterknife 8.*的時候就需要引入

compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'

21、dp 、 px Android適配

相關blog: http://www.jianshu.com/p/ec5a1a30694b

這裏寫圖片描述


20、Recyclerview滑動時item顯示錯亂

1、在重用控件中,最重要的細節是:有if一定得有else,而且,不管是true還是false都要設置。
2、對於複用,可以在Bean對象中加一個字段用來標識,或者使用集合來記錄位置。


19、java 判斷string數組中是否有某個字符串

1.把數組各項放到list中,用list的contain判斷;

//定義數組
String aa []={"timo","kainan","naer","lanbo"};
//數組轉換成list
List<String> list=Arrays.asList(aa);
if(list.contains("timo")){...

2.遍歷數組,逐條比較。

   String[] strList = new String[]{"aaaa","bbbb","cccc"};    
    for(int i = 0;i<strList.length;i++){        
        if(strList[i].contains("aaaa")){            
            //包含aaaa        
         }else{ 
           //不包含aaaa        
         }    
     }  

18、Java比較兩個數組中的元素是否相同的最簡單方法

 public static void main(String[] args) {  
                       String [] array1 = {"1","2","3"};  
                       String [] array2 = {"3","2","1"};  
                       Arrays.sort(array1);  
                       Arrays.sort(array2);  
                       if (Arrays.equals(array1, array2)) {  
                               System.out.println("兩個數組中的元素值相同");  
                       } else {  
                               System.out.println("兩個數組中的元素值不相同");  
                       }  
               }  

1、String的trim()方法

參考blog:http://blog.csdn.net/muyu114/article/details/5734295

String.Trim()方法會去除字符串兩端,不僅僅是空格字符,它總共能去除25種字符:
(‘/t’, ‘/n’, ‘/v’, ‘/f’, ‘/r’, ’ ‘, ‘/x0085’, ‘/x00a0’, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ’ ‘, ‘?’, ‘/u2028’, ‘/u2029’, ’ ‘, ‘?’)

如果你想保留其中的一個或多個(例如/t製表符,/n換行符,/r回車符等),請慎用Trim方法。

請注意,Trim刪除的過程爲從外到內,直到碰到一個非空白的字符爲止,所以不管前後有多少個連續的空白字符都會被刪除掉。

去除字符串頭部空白字符的TrimStart方法和去除字符串尾部空白字符的 TrimEnd方法

如果想去除字符串兩端其他任意字符,可以考慮Trim他的重載兄弟:String.Trim(Char[]),傳入你想要去除的哪些字符的數組。

空格 != 空白字符,刪除空格請使用: Trim(‘ ‘);


2、Activity的isFinishing()方法

原因:若Activity調用了finish(),再調用Dialog\handlerMessage\接收廣播等等需要Activity實例的方法時,會導致bug。

解決:使用isFinishing()方法判斷Activity是否finish,再進行相關操作。


3、Android圖片選擇器框架GalleryFinal

原始地址:https://github.com/pengjianbo/GalleryFinal

遷移地址:https://github.com/FinalTeam/RxGalleryFinal

使用參考blog:https://segmentfault.com/a/1190000004263541?_ea=549747

可基於GalleryFinal定製自己的圖片選擇界面


4、本地圖片獲取

通過uri獲取bitmap對象

Bitmap bitmap = MediaStore.Images.Media.gitBitmap(this.getContentResolver(),uri);


5、使用第三方庫儘量進行二次封裝

尤其是做大型項目或長遠發展項目的時候,方便後期更換框架,降低耦合度。


6、AS快捷鍵

Cltr+Alt+F7,顯示方法在哪裏使用過
Cltr+Alt+L,代碼格式化


7、Fiddler是一個很好的代理工具,可以抓取協議請求用於調試


8、EditText 的 imeOptions屬性

配合singleLine = “true”使用

actionGo — 前往

actionDone — 完成

actionNext — 下一項

actionNone — 回車

actionPrevious — 上一項

actionSend — 發送

actionSearch — 搜索

其他


9、使用Bugly的時候

兩個bulid.gradle文件都要做修改

app目錄下的:

apply plugin: 'bugly' //添加Bugly符號表插件

compile 'com.tencent.bugly:crashreport:2.1.5'

bugly {
appId = '6c03c11b61' //註冊時分配的App ID
appKey = '88f0e552-87fd-43cb-b34b-e102921dc8f1' //註冊時分配的AppKey
// excute = true
// upload = true
}

project目錄下的: classpath 'com.tencent.bugly:symtabfileuploader:1.3.4'//bugly


10、全局變量、標識符的提取

項目中多個地方使用到的變量、標識符,需要提取到一個單獨的類中,避免混淆以及修改時的麻煩


11、APP主題做法

思路:把相關的圖片、color的使用、全局變量都指向同一文件Theme.xml, 更換主題 就是控制Theme文件中的選擇


12、常用的評分代碼RatingBar

1、定義自己的progressDrawable,例如rating_bar_layer.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/star_unchecked">
    </item>
    <item
        android:id="@android:id/secondaryProgress"
        android:drawable="@drawable/star_unchecked">
    </item>
    <item
        android:id="@android:id/progress"
        android:drawable="@drawable/star_checked">
    </item>
</layer-list>

2、定義自己的Style.xml

    <style name="ratingBar" parent="@android:style/Widget.RatingBar">
        <item name="android:progressDrawable">@drawable/rating_bar_layer</item>
        <item name="android:numStars">5</item>
        <item name="android:stepSize">1</item>
        <item name="android:maxHeight">23dp</item>
        <item name="android:minHeight">23dp</item>
        <item name="android:columnWidth">10dp</item>
    </style>

3、項目中使用

 <RatingBar
        android:id="@+id/rb_normal"
        style="@style/ratingBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

13、需要關閉的操作、一定要及時關閉

比如:IO流db操作結束後,需要db.close()使用到cursor的時候,要記得cursor.close()等等


14、asset和raw文件夾區別

res/raw目錄的文件會被映射到R.java中。asset中的文件不會。

res/raw目錄下不可再建文件夾,asset可以。

讀取:
getResoures().openRawResource();

getAssets().open();


14、Fragment在切換的時候被銷燬

項目中幾次遇到這樣的情況,一般項目框架都是由4個或者5個fragment組成,且經常需要切換,好幾次都是切換的時候,原來的頁面上的數據顯示不了了,解決方法就是不讓fragment銷燬,也就4-5個fragment,不銷燬也不會太佔內存。
解決方法:

  • 改變預加載頁數
viewPager.setOffscreenPageLimit(2);
  • 在Fragment的onCreateView方法中處理
private View view;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (view== null) {
            view= inflater.inflate(R.layout.fragment, container, false);
        //初始化處理
        initView();
        } else {
            ViewGroup viewGroup = (ViewGroup) view.getParent();
            if (viewGroup != null)
                viewGroup.removeView(view);
        }
        return view;
    }

15、 Android 複雜的列表視圖界面繪製

這裏寫圖片描述

如上圖: 我們可以使用alibaba開源的vlayout 框架,github 地址:https://github.com/alibaba/vlayout

系列文章
http://pingguohe.net/2017/02/28/vlayout-design.html
http://pingguohe.net/2017/03/03/vlayout-guide-1.html
http://pingguohe.net/2017/03/03/vlayout-guide-2.html

還可以使用這個庫—drakeet/MultiType,作者也是就職於阿里的android開發攻城獅

github 鏈接:https://github.com/drakeet/MultiType

詳解文章:https://drakeet.me/effective-multitype


16、 將集合數據反轉排序

集合有個工具類Collections,直接調用其靜態方法,對集合排序反轉:Collections.reverse(list);


17、 應用中視頻播放

使用Vitamio會出現錯誤,可以試試Bilibili的ijkplayer。
https://github.com/yixia/VitamioBundlehttps://github.com/yixia/VitamioBundle/issues/385
到android 7.0 會有問題 ,可以看下這個 https://github.com/Bilibili/ijkplayer

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章