Android 開發偷懶技巧之工具代碼片

  1. Iconfont在Android中的使用
    阿里提供的Iconfont-國內功能很強大且圖標內容很豐富的矢量圖標庫,提供矢量圖標下載、在線存儲、格式轉換等功能。
    如何使用:

    • 從iconfont平臺選擇要使用到的圖標
    • 下載代碼,把iconfont.ttf文件導入到項目中的assets中的iconfont文件夾中
    • 用TextView代替ImageView,找到圖標相對應的 HTML 實體字符碼給textView設置
    • textview設置大小跟顏色,圖標的大小顏色也會改變
    • 爲Textview設置指定的ttf文字
    <TextView
        android:id="@+id/icon_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="&#xe66e"
        android:textColor="@color/red"
        android:textSize="50dp"/>
    
    //爲TextView設置指定ttf文字
    Typeface iconfont = Typeface.createFromAsset(getAssets(), "iconfont/iconfont.ttf");
    TextView textview = (TextView)findViewById(R.id.icon_text);
    textview.setTypeface(iconfont);
    

    上述方法可以使用iconfont了,但是每次都給TextView設置指定setTypeface是不是也很繁瑣,而且一直不斷的在讀取iconfont.ttf文字,也很浪費內存,所以就想到封裝一個工具類。代碼如下:

    public class FontHelper {
        public static final String DEF_FONT = "iconfont/iconfont.ttf";
    
        public static final void injectFont(View rootView) {
            injectFont(rootView, Typeface.createFromAsset(rootView.getContext().getAssets(),
                DEF_FONT));
        }
    
        private static void injectFont(View rootView, Typeface typeface) {
            if (rootView instanceof ViewGroup) {
                ViewGroup viewGroup = (ViewGroup) rootView;
                int childViewCount = viewGroup.getChildCount();
                for (int i = 0; i < childViewCount; i++) {
                    injectFont(viewGroup.getChildAt(i), typeface);
                }
            } else if (rootView instanceof TextView) {
                ((TextView) rootView).setTypeface(typeface);
            }
        }
    }
    

    這樣我們每次調用FontHelper.injectFont(textview)就可以了,你可能會說這還不是我想要的,我連這行代碼都不想多寫,那好,接着往下看:我們可以自定義一個TextView然後初始化時setTypeface即刻,代碼如下:

    public class TextViewIcon extends AppCompatTextView {
        public TextViewIcon(Context context) {
            super(context);
            init(context);
        }
        public TextViewIcon(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
        public TextViewIcon(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context);
        }
        private void init(Context context) {
            setTypeface(Typeface.createFromAsset(context.getAssets(),"iconfont/iconfont.ttf"));
        }
    }
    

    現在我們在佈局文件中寫如下代碼即可:

    <com.xxx.xxx.TextViewIcon 
        android:id="@+id/icon_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="&#xe66e"
        android:textColor="@color/red"
        android:textSize="50dp"/>
    

    可是我也想實現像普通textview動態改變文字一樣動態改變iconfont的效果怎麼辦呢?也就是說在代碼裏動態的調整圖標的大小顏色或改變圖片,iconfont改變大小顏色這很簡單直接調用TextView的setTextSize和setTextColor就可以了,動態設置圖片是不是setText呢?
    textview.setText("");
    你會發現這並不會如你所願顯示對應的圖片效果,因爲這裏涉及到unicode 字符的問題。所以將"&#x" 替換成 "\u",用 unicode 字符來表示,即代碼如下:
    textview.settext("\ue66e");

  2. Scrollview 自動滾動到頂部或者底部

    • 設置默認滾動到頂部
      scrollView.post(new Runnable() {
      @Override
      public void run() {
      // TODO Auto-generated method stub
          scrollView.fullScroll(ScrollView.FOCUS_UP);
       }
      });
      
    • 設置默認滾動到底部
       scrollView.post(new Runnable() {
       @Override
       public void run() {
       // TODO Auto-generated method stub
             scrollView.fullScroll(ScrollView.FOCUS_DOWN);
       }
      });
      
  3. 判斷App的運行狀態

     /**
      * 返回app運行狀態
      * 1:程序在前臺運行
      * 2:程序在後臺運行
      * 3:程序未啓動
      * 注意:需要配置權限<uses-permission android:name="android.permission.GET_TASKS" />
      */
     public static int getAppSatus(Context context, String pageName) {
    
         ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(20);
    
         //判斷程序是否在棧頂
         if (list.get(0).topActivity.getPackageName().equals(pageName)) {
             return 1;
         } else {
             //判斷程序是否在棧裏
             for (ActivityManager.RunningTaskInfo info : list) {
                 if (info.topActivity.getPackageName().equals(pageName)) {
                     return 2;
                 }
             }
             return 3;//棧裏找不到,返回3
         }
     }
    
  4. 根據圖片寬度自適應圖片控件的高度

      /*將ImageView 根據寬度自適應高度(此處假設寬度>高度)*/
     public static void adaptiveHeightByWidth(ImageView view, int width){
         ViewGroup.LayoutParams lp = view.getLayoutParams();
         lp.width = width;
         lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
         view.setLayoutParams(lp);
         view.setMaxWidth(width);
         view.setMaxHeight(width);
     }
    
  5. Android 中如何調試webview

    • .在APP中啓用 WebView 調試,開啓調試後,Chrome DevTools才能對WebView進行遠程調試;
      在對應的android頁面中添加如下代碼:
      WebView.setWebContentsDebuggingEnabled(true);
    • 通過Chrome瀏覽器訪問chrome://inspect/#devices訪問已啓用調試的 WebView 列表;
    • 調試Webview與遠程調試普通頁面相同,遠程調試普通頁面也就是在安卓手機中安裝Chrome瀏覽器,使用USB 連接 PC,然後在 PC 的 Chrome 瀏覽器中打開 chrome://inspect/#devices 即可。
    • 點擊inspect 進入dev_tools 頁面可能碰到404 Not Found錯誤,那是因爲你在國內,FQ即可。
  6. Android按Home鍵避免重啓程序
    問題描述:
    在App打開後按Home鍵後應用退至後臺運行,此時點擊應用圖標再次打開App,發現App重新啓動,難道打開程序的頁面不應該是在按Home鍵之前的頁面嗎?
    解決方案:
    在啓動頁也就是應用程序剛進入的Activity 即大部分都爲閃屏頁,在OnCreate方法中是在setContentView之前加入下面的代碼還是在setContentView之後加入一下代碼都可以。

     if (!this.isTaskRoot()) {
        Intent mainIntent = getIntent();
        String action = mainIntent.getAction();
        if (mainIntent.hasCategory(Intent.CATEGORY_LAUNCHER) 
            && action.equals(Intent.ACTION_MAIN)) {
                finish();
                return;
         }
     }
    
  7. Android中使用Glide獲取網絡圖片的寬高比

    public class ImageUtil {
     /**
      * 根據圖片鏈接獲取圖片寬高比
      * @param context
      * @param imgUrl
      * @return  高/寬
      */
     public static void getAspectRatioByImgUrl(Context context, String imgUrl, ImageAspectRatioCallBack aspectRatioCallBack){
         if (TextUtils.isEmpty(imgUrl)){
             return;
         }
         //獲取圖片真正的寬高
         Glide.with(context)
                 .load(imgUrl)
                 .asBitmap()//強制Glide返回一個Bitmap對象
                 .into(new SimpleTarget<Bitmap>() {
                     @Override
                     public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
                         int width = bitmap.getWidth();
                         int height = bitmap.getHeight();
                         Log.e(Constant.LOG_TAG, "width " + width);
                         Log.e(Constant.LOG_TAG, "height " + height);
                         if (width > 0 && aspectRatioCallBack != null){
                             aspectRatioCallBack.returnAspectRation((float) height/width);
                         }
                     }
                 });
      }
    
      public interface ImageAspectRatioCallBack {
         void returnAspectRation(float aspectRatio);
      }
    }
    
  8. Android中webview嵌套H5頁面報錯"Uncaught Error: Java exception was raised during method invocation"
    問題描述:
    客戶端提供給H5一個方法供其修改原生頁面標題的頭部顯示信息,代碼如下:

       @JavascriptInterface
       public void resetTitle(String title2) {
        mTitleTv.setText(title2);
       }
    

    結果H5在調用該方法時就會報此錯誤,原因是因爲@JavascriptInterface 註解的方法裏面不能更新ui.
    解決方案:

       @JavascriptInterface
       public void resetTitle(String title2) {
        BrowserActivity.this.runOnUiThread(new Runnable() {
               @Override
                   public void run() {
                    mTitleTv.setText(title2);
                   }
               });
       }
    
  9. 查看android手機中安裝apk的包名等信息

  • 方法一:
    進入cmd窗口,輸入adb shell,進入手機,在輸入ls /data/data,即能顯示出手機中安裝apk的包名。(需要root權限)
  • 方法二:
    查看手機中非系統的apk包名信息,adb shell pm list package -3,這個命令很實用。這和命令後面不加-3表示查看手機中使用的apk包名。
  • 方法三:
    在代碼中獲取Android設備中apk的包名等信息。
     /*獲取Android手機中安裝的應用*/
      public static void getAllAppPackages(Context context) {
          Intent intent = new Intent(Intent.ACTION_MAIN, null);
          intent.addCategory(Intent.CATEGORY_LAUNCHER);
          List<ResolveInfo> apps = context.getPackageManager().queryIntentActivities(intent, 0);
          //for循環遍歷ResolveInfo對象獲取包名和類名
          for (int i = 0; i < apps.size(); i++) {
              ResolveInfo info = apps.get(i);
              String packageName = info.activityInfo.packageName;
              CharSequence cls = info.activityInfo.name;
              CharSequence name = info.activityInfo.loadLabel(context.getPackageManager());
              Log.e(Constant.LOG_TAG,name+"----"+packageName+"----"+cls);
          }
      }
    
  1. 解決使用HttpURLConnection讀取網絡文件亂碼問題
    public static void getRemoteMockApiData(final String mockdataUrl, final JsonCallBack jsonCallBack){
        final StringBuilder stringBuilder = new StringBuilder();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //構建URL地址
                    URL url = new URL(mockdataUrl);
                    try {
                        HttpURLConnection hcont = (HttpURLConnection) url.openConnection();
                        hcont.setRequestProperty("Content-Type", "application/json");
                        hcont.setDoOutput(true);
                        hcont.setRequestMethod("GET");
                        hcont.setRequestProperty("Accept-Charset", "utf-8");
                        hcont.setRequestProperty("contentType", "utf-8");
    
                        if (hcont.getResponseCode() == 200) {
                            InputStreamReader in = null;
                            in = new InputStreamReader(hcont.getInputStream(),"utf-8");
                            BufferedReader bufferedReader = new BufferedReader(in);
                            String line = null;
                            while ((line = bufferedReader.readLine()) != null) {
                                stringBuilder.append(line);
                            }
                        }
    
                        if (jsonCallBack != null){
                            jsonCallBack.getRemoteMockData(stringBuilder.toString());
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    
  2. 基於android studio 3.1.4將library生成jar和arr文件
    其實Android Studio編譯的時候會自動將library項目生成jar和aar的,分別在build/outputs/aarbuild/intermediates/packaged-classes文件夾下。
  • 在對應的module文件下的build.gradle中添加以下代碼:
    task makeJar(type: Copy) {
    //刪除存在的
     delete 'build/libs/react-native-bridge.jar'
    //設置拷貝的文件
     from('build/intermediates/packaged-classes/release/')
    //打進jar包後的文件目錄
     into('build/libs/')
    //將classes.jar放入build/libs/目錄下
     include('classes.jar')
     rename ('classes.jar','react-native-bridge.jar')
    }
    makeJar.dependsOn(build)
    
  • 選中library的Module,點擊Build -> Make Module library,此時packaged-classes目錄即可生成。
  • 在AS最下方的Terminal中輸入命令即可。
    1. MAC電腦:
      ./gradlew makeJar
    2. Windows電腦:
      gradlew makeJar
  • 順利的話就可以在build/libs文件夾下看到生成的jar文件。

ADB命令:
獲取手機CPU型號:adb shell getprop ro.product.cpu.abi

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