Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發Tips(5)

Android開發Tips(5)

編輯:關於Android編程

Tips


1. 模擬系統回收Activity.

使用adb命令可以模擬Android系統自動回收Activity進程, 可以調試這個效果.
單進程

adb shell am force-stop [包名]

多進程

adb shell ps | grep [包名]
adb shell kill [PID]

2. Android庫動態權限建議

Android 6.0使用動態權限, 在創建第三方庫時, 需要充分考慮這一特性.
(1) 在自動Merge庫的AndroidManifest時, 需要提供危險權限的提示文檔.
(2) 當權限未獲取時, 用戶可以使用庫的某一部分, 並提示缺少權限.
(3) 需要提供在權限獲取失敗時, 庫使用方式的文檔.
(4) 確保所有權限都是必須的, 不含有未使用權限.

關於提示用戶獲取權限的解決方案, 可以參考.


3. RxJava處理Retry請求服務器

服務器經常會出現異常, 應用需要連續嘗試請求, RxJava可以非常簡單的實現.

模板

Observable source = ...; // Something that eventually emits true

source
    .repeatWhen(completed -> completed.delay(1, TimeUnit.SECONDS))
    .takeUntil(result -> result)
    .filter(result -> result)
    .subscribe(
        res -> System.out.println("onNext(" + res + ")"),
        err -> System.out.println("onError()"),
        () -> System.out.println("onCompleted()")
    );

示例

/**
 * This is a class that should be
 * mapped on your json response from the server
 */
class ServerPollingResponse {
    boolean isJobDone;

    @Override
    public String toString() {
        return "isJobDone=" + isJobDone;
    }
}

Subscription checkJobSubscription = mDataManager.pollServer(inputData)
        .repeatWhen(new Func1, Observable>() {
            @Override
            public Observable call(Observable observable) {
                Log.v(TAG, "repeatWhen, call");
                /**
                 * This is called only once.
                 * 5 means each repeated call will be delayed by 5 seconds
                 */
                return observable.delay(5, TimeUnit.SECONDS);
            }
        })
        .takeUntil(new Func1() {
            @Override
            public Boolean call(ServerPollingResponse response) {
                /** Here we can check if the responce is correct and if we should
                 *  finish polling
                 *  We finish polling when job is done.
                 *  In other words : "We stop taking when job is done"
                 */
                Log.v(TAG, "takeUntil, call response " + response);
                return response.isJobDone;
            }
        })
        .filter(new Func1() {
            @Override
            public Boolean call(ServerPollingResponse response) {
                /**
                 * We are filtering results if we return "false".
                 * Filtering means that onNext() will not be called.
                 * But onComplete() will be delivered.
                 */
                Log.v(TAG, "filter, call response " + response);
                return response.isJobDone;
            }
        })
        .subscribe(
                new Subscriber() {
                    @Override
                    public void onCompleted() {
                        Log.v(TAG, "onCompleted ");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.v(TAG, "onError ");
                    }

                    @Override
                    public void onNext(ServerPollingResponse response) {
                        Log.v(TAG, "onNext response " + response);
                        // Do whatever you need. Server polling has been finished
                    }
                }
        );

參考和參考.


4. Chrome的JsonView插件

添加插件之後, 可以格式化的顯示Json數據.

JsonView


5. 顯示Activity棧的Shell命令

Shell命令

adb shell dumpsys activity | sed -n -e '/Stack #/p' -e '/Running activities/,/Run #0/p'

直接獲取Activity信息有些冗余, 我們只關注堆棧信息即可.
sed可以編輯顯示的文字.
-n, 從截取處開始連續處理.
-e, 多選參數.
'/Stack #/p', 輸出含有Stack #的行.
-e '/Running activities/,/Run #0/p', 輸出從Running activitiesRun #0的所有行.

輸出結果

  Stack #1:
    Running activities (most recent first):
      TaskRecord{299f41ea #2269 A=me.chunyu.spike.wcl_activity_launchmode_demo U=0 sz=6}
        Run #5: ActivityRecord{33926043 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2269}
        Run #4: ActivityRecord{3f181566 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2269}
        Run #3: ActivityRecord{22737e45 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2269}
        Run #2: ActivityRecord{ce0a990 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2269}
        Run #1: ActivityRecord{3de8e378 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2269}
        Run #0: ActivityRecord{1cb28ec4 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2269}
  Stack #0:
    Running activities (most recent first):
      TaskRecord{bfee9cf #2241 A=com.miui.home U=0 sz=1}
        Run #0: ActivityRecord{279bc098 u0 com.miui.home/.launcher.Launcher t2241}

6. dp和sp的區別

dp是Android頁面常用的度量單位, sp主要用於字體度量.
在標准情況下, dp等於sp. 然而, Android系統允許用戶設置字體大小, sp會隨著字體的大小而改變, 放大或是縮小.
設置位置(紅米): Android -> 設置 -> 字體大小 -> 標准(默認)或大小號.


7. AlertDialog獲取全部屏幕監聽

在Android 4.0以上, AlertDialog在觸摸對話框邊緣外部時, 對話框消失.
在AlertDialog.Builder.create(), 可以設置屬性獲取屏幕監聽.
方法一:

setCanceledOnTouchOutside(false);

調用這個方法時, 按對話框以外的地方不起作用. 按返回鍵仍起作用.

方法二:

setCancelable(false);

調用這個方法時, 按對話框以外的地方不起作用. 按返回鍵也不起作用.


8. getColor遺棄

最新版本的getColor被遺棄(deprecated), 使用時, 需要添加主題.
也可以使用兼容模式, 即

ContextCompat.getColor(context, R.color.your_color);

ContextCompat.getColor的源碼

public static final int getColor(Context context, int id) {
    final int version = Build.VERSION.SDK_INT;
    if (version >= 23) {
        return ContextCompatApi23.getColor(context, id);
    } else {
        return context.getResources().getColor(id);
    }
}

9. libarchive和expat簡介

libarchive
Multi-format archive and compression library. 多格式存檔和壓縮庫.
Android的toolchain使用libArchive.
參考

expat
Expat is an XML parser library written in C. Expat是用C語言寫的XML解析庫.
Android的Platform的擴展.
參考

libarchive 2.8.4和expat 2.1.0會產生漏洞, 如需修復, 需要升級Android的編譯版本.


10. 網頁重定向

默認鏈接會跳轉其他鏈接, 根據鏈接內容, 進行相應操作, 如下載Apk等. 如果使用重定向, 則返回false; 如果非重定向, 則返回true.

        WebViewClient webClient = new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url.endsWith(".apk")) {
                    DownloadUtils.downloadFiles(url);
                    if (mStartDownloadAppListener != null) {
                        mStartDownloadAppListener.doAfter();
                    }
                    return true;
                }
                return false;
            }
        };
        setWebViewClient(webClient);

OK, that’s all! Enjoy it!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved