アリAndroidの26 Tiao仕様と最適化の経験

アリAndroidの26 Tiao仕様と最適化の経験

図1に示すように、活性との間のデータ通信、大量のデータのために、Parcelable +意図方法を使用することを避けるために、他の選択肢がEventBusを避けるTransactionTooLargeExceptionと考えることができます

2は、暗黙のうちにテントの活動の間にジャンプすることにより、意図発行する前に、コンポーネントを呼び出すと、異常ActivityNotFoundExceptionの右の原因を見つけることができませんresolveActivityの回避によってチェックされなければなりません。

public void viewUrl(String url, String mimeType) {
 Intent intent = new Intent(Intent.ACTION_VIEW);
 intent.setDataAndType(Uri.parse(url), mimeType);
 if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_
ONLY) != null) {
 try {
 startActivity(intent);
 } catch (ActivityNotFoundException e) {
 if (Config.LOGD) {
 Log.d(LOGTAG, "activity not found for " + mimeType + " over " +
Uri.parse(url). getScheme(), e);
 }
 }
 }
}

図3は、回避時間のかかる操作BroadcastReceiver#onReceive()に、時間のかかる作業がある場合は、完全なIntentServiceを作成する必要がありますし、BroadcastReceiverで行うには子スレッドを作成しないでください。

説明:

この方法は、メインスレッドで実行されているので、時間のかかる操作が原因となる場合、UIはスムーズされていません。あなたは、IntentServiceを使用HandlerThreadを作成したり、#registerReceiverコンテキスト呼び出すことができ
、他のWroker onReceiveスレッドでメソッドを実行する(BroadcastReceiver、IntentFilter、文字列、ハンドラ)の方法などを、。BroadcastReceiver#onReceive()メソッドは、システムが殺されるかもしれ、10秒以上かかります

4、暗黙インテントブロードキャスト機密情報の使用を回避する、他の情報は、対応する登録されていてもよい
BroadcastReceiverを受信アプリ。

説明:

()暗黙放送はすべての利害悪意のあるアプリケーションがテントに渡される機密情報、およびその他の危険な操作を得ることができる放送受信機を聞くように登録sendBroadcast受信機のコンテキスト#を介して受信されます。放送順序を送信するコンテキスト#sendOrderedBroadcast()メソッドを使用して同報送信した場合、より高い優先順位は、放送サービスが放送結果にデータ悪意のある又はスタッフィング利用できない結果である悪意のある受信廃棄してもよいです。放送は、アプリケーション内に限定されている場合は、機密情報の漏洩や意図の傍受の危険性を回避するために、LocalBroadcastManager#sendBroadcast()の実装を使用することができます

Intent intent = new Intent("my-sensitive-event");
intent.putExtra("event", "this is a testevent");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent

図5は、)(アクティビティ#onDestroyのワークリリースリソースを実行しない、後で実行することができるタイミングonDestroy()ので、そのような糸のようないくつかの作業の破壊を止めます。実際のニーズに応じて、アクティビティ#onPause()/ onStop()でisFinishing()を決定することに関連して行います。

6、このような非必須であると、ネストされた断片の使用を避けるために。

説明:

次のようにAndroidのAPI 17にネストフラグメントSDKとサポートライブラリの機能に追加され、断片巣バグが発生しやすいいくつかのピットがあるでしょうが、より一般的な問題が要約されています。

1)onActivityResult障害()メソッドを処理して、埋め込まれた断片は、コールバックメソッドを受信しない可能性があり、
;フラグメントは転送ホストによって処理される必要がある
; 2)変異アニメーション
フラグメントの再構成をもたらす、3)継承setRetainInstance()複数のトリガ不要なロジック。

ネストされた断片の使用を避けるために、可能な限り非本質的なシーン、してください。なお、上述した問題の使用のために。

図7に示すように、電流は、ページ間のジャンプの効率に影響を与えるであろう、この方法は、時間のかかる作業には適していないonPauseので、活動onPause法の終了後に実行のアクティビティのonCreateメソッド次へ実行されます

8、Androidのアプリケーションオブジェクト内のキャッシュされていないデータを実行します。ベースコンポーネント意図使用する他の機構との間のデータの共有はまた、機構SharedPreferences永続データのように使用することができます

class MyApplication extends Application {
 String username;
 String getUsername() {
 return username;
 }
 void setUsername(String username) {
 this.username = username;
 }
}

トーストを使用した場合9は、トースト(Toast.makeTextの使用を避け、あなたが連続ポップトーストを持っている場合)は、メッセージが連続して表示されたらトーストトーストをキャンセルすることができないときの状況を避けるために、グローバルオブジェクトを定義することをお勧めします

図10に示すように、アダプタの使用、あなたがViewHolderを使用する場合はnullとすることができるように、テキストのTextViewセットとしてかかわらず、それぞれの子コントロールのニーズのconvertViewプロパティを(設定するかどうかのキャッシング、メソッドgetViewメソッドを()を実行、ボタン透明に背景色、透明コントロール、等)、明示的に設定された属性への必要性も透明な背景を設定し、(テキストのTextViewも空集合のsetText(「」である))、またはスライドの過程でアダプタ項目を多重化、コンテンツが存在しますので、混乱を表示

アクティビティまたはフラグメントを動的にペアリングする)BroadCastReceiver、registerReceiver()とunregisterReceiver(登録11、。

説明:

registerReceiver()とunregisterReceiver()がメモリリークにつながる、それが既に適切なタイミングで償却登録されていない受信機をもたらす可能性が表示されない場合、メモリ空間は、エコプリンティングの負担を増やすこと、占領しました。

リソース管理と制御を受信機になるHuaweiのモデルの一部は、単一の登録申請は、過剰な受信機制御モジュールは例外、クラッシュへの直接適用をスロートリガされます。

12は、レイアウトが複数のネストされたのViewGroupを使用していたとき、のLinearLayoutは賛成RelativeLayoutにネストされて使用していない、効果的にネストの数を減らすことができます。

説明:

表示ページのAndroidアプリケーションは、任意の測定、レイアウトを経る正しくレンダリングするために、3つのステップを描画する必要があります。測定を開始するには、XMLレイアウトの最上位ノードから、それぞれの子は、このプロセスでも、再測定することができ、彼らの親ノードにショーの位置を決定するために、独自のサイズを提供するために消費する元のメジャー時間につながる可能性があり(必要があります。 2-3回)。ノードの深い場所、より多くのネストされたもたらした尺度は、計算はより多くの時間がかかります。フラットビュー構造は、パフォーマンスをより良いでしょう理由はここにあります。

また、より多くのページビュー、長い時間測定、レイアウト上のホールド、引き分けがかかります。この時間を短縮するために、キーは可能なツリー構造表示を平らに保つために、すべての不要なレンダリングビューを削除することです。理想的には、測定、レイアウトの合計は、滑らかスライディングUI画面を確保するために、時間が十分に16msの未満に制御されるべきである描きます。

それらの余分ビューを(増加描画遅延が表示)を見つけるために、あなたはHierarachyビューアツール、視覚的なビューすべてのビューにAndroidのスタジオモニターを使用することができます

図13に示すように、ダイアログボックスやポップアップ表示毛布、DialogFragmentを利用するためには、むしろ活動に比べて
ダイアログ/ AlertDialog、それが活動のライフサイクル管理ダイアログ/ポップライフサイクル浮動層で簡単です

14、文字サイズ、単位DPを使用するには、単位DPの使用の大きさを表示します。TextViewのために、テキストディスプレイアダプタの問題を回避するために、テキストのサイズを決定する場合の場合に推奨wrap_contentレイアウトが不完全表示されます。

15、スレッドプールは、エグゼキューを作成するために許可されていないが、ThreadPoolExecutorの方法により、このアプローチは、学生が資源の枯渇の危険性を回避するために、スレッドプールより明示的な運用ルールを記述することができます。

説明:

次のように執行医療過誤スレッドプールオブジェクトが返されました:

1)FixedThreadPoolとSingleThreadPool:それによってOOM原因は、Integer.MAX_VALUEは、多数の要求を蓄積し得る許可要求キューの長さ、
2)及びCachedThreadPool ScheduledThreadPoolを:多数のスレッドを作成することができ、許容Integer.MAX_VALUEのスレッドの数が作成され、 OOMを結果。

正例:

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
int KEEP_ALIVE_TIME = 1;
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES, 
NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, 
taskQueue, new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());

反例:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

外部メモリ、外部メモリはの可用性を確認しなければならない16、

// 读/写检查
public boolean isExternalStorageWritable() {
 String state = Environment.getExternalStorageState();
 if (Environment.MEDIA_MOUNTED.equals(state)) {
 return true;
 }
 return false;
}
// 只读检查
public boolean isExternalStorageReadable() {
 String state = Environment.getExternalStorageState();
 if (Environment.MEDIA_MOUNTED.equals(state) ||
 Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
 return true;
 }
 return false;
}

)SharedPreference)はエディタ#の使用は、(適用するためにデータを送信するのではなく、エディタ位(コミット17、。一般的に、あなただけが時に結果を提出するかを決定する必要があり、それに応じてのみ()エディタ#コミット使用して、その後の操作があります。

説明:

SharedPreference関連の改正は、前記第一のメモリに書き込み、その後、非同期的にディスクに書き込まれ、法を犯すだろうがディスクに直接書き込まれる適用を使用して提出しました。頻繁に操作した場合、その後、ディスクに書き込まれた内容を修正続く適用、パフォーマンスが良くコミットよりになります適用されます。あなたはすぐに応じて適宜結果ストレージ操作、および他の操作を取得したい場合しかし、あなたはコミット使用する必要があります。

18、データベースカーソルは、メモリリークを回避するために、終了後ことを確認しなければなりません。
データベースにするとマルチスレッドの動作は、同期の問題を回避するために、トランザクションを使用する必要があります。
SQL文を実行するときは、使用する必要がありますSQLiteDatabase#挿入()、更新(削除)、()、 SQLインジェクションのリスクを避けるために、)(SQLiteDatabase#ExecSqlのを使用していません

19は、大画面または使い捨てローディング複数の画像をロードし、それが非同期スレッドで行われるべきです。ロード、IO操作に関連して、CPU集約型のオペレーションの写真は、カトンを引き起こす可能性があります。

リストビュー、ViewPager、RecyclerView、GirdViewおよび他の成分の画像の使用は、キャッシュイメージを準備する必要があり20、常に回避する画像メモリリークを保持するだけでなく、回避するために、パフォーマンスの問題を引き起こし、画像を作成して複製。推奨フレスコ(https://github.com/facebook/fresco)グライド(https://github.com/bumptech/glide)などのフォトギャラリー

21、パッケージの容積を減少させるために、圧縮プロセスtinypngまたは同様のツールを使用して画像をPNG形式

22、Activity.onPauseに()またはActivity.onStop()が実行されている現在のアクティビティアニメーションを閉じるためにコールバック。

新しいメモリを開くの重複を避けるために、inBitmap再利用メモリ空間を使用して23、

private static void addInBitmapOptions(BitmapFactory.Options options,
 ImageCache cache) {
 // inBitmap 只处理可变的位图,所以强制返回可变的位图
 options.inMutable = true;
 if (cache != null) {
 Bitmap inBitmap = cache.getBitmapFromReusableSet(options);
 if (inBitmap != null) {
 options.inBitmap = inBitmap;
 }
 }
}

24は、代わりに使用ARGB_565 ARGB_888最もシーンを使用する
ARGB_8888とRGB_565をRGB_565が大幅に画像の品質を確保する上でメモリのオーバーヘッドを減らすことができ、それは方法のOOM溶液です。

しかし、我々はあなたが絵自体の透明性を維持したい場合は、あなたがRGB_565を使用することはできません、何の透明度RGB_565が存在しないことに注意しなければなりません

1)グライドビットマップ形式は、ピカソがARGB_8888のデフォルトフォーマットであるが、メモリのオーバーヘッドが小さく半分で、デフォルトフォーマットRGB_565ある
グライドキャッシュ仕様の多様であるが、キャッシュはピクチャのみピカソ元のサイズので、ディスクキャッシュの点で)2グライドは、あなたのImageViewのサイズとして、あなたのImageViewの画像サイズ、適切なサイズの大きさに基づいてキャッシュされることを意味している200200で、アートワークは400400で、グライドを使用して200200は、マップの仕様をキャッシュされ、ピカソの仕様は唯一の400400をキャッシュ。この改善はあまり再レンダリングプロセスの各カット、すべての後に、より速くロードピカソの速度よりもグライドにつながります。
3)最も重要な特徴は、グライドのGIFダイナミック・ロードマップのサポートで、ピカソはこの機能をサポートしていません。

メモリフットプリントを減らす25、画像圧縮、

使用inSampleSizeサンプリングレート低減

public static Bitmap getFitSampleBitmap(String file_path, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file_path, options);
options.inSampleSize = getFitInSampleSize(width, height, options);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(file_path, options);
}
public static int getFitInSampleSize(int reqWidth, int reqHeight, BitmapFactory.Options options) {
int inSampleSize = 1;
if (options.outWidth > reqWidth || options.outHeight > reqHeight) {
int widthRatio = Math.round((float) options.outWidth / (float) reqWidth);
int heightRatio = Math.round((float) options.outHeight / (float) reqHeight);
inSampleSize = Math.min(widthRatio, heightRatio);
}
return inSampleSize;
}

利用マトリックス

小さな、小さなマトリックスDayong図有するより大きなサンプル。

あるいは、前の例のファジー画像を使用して、我々はまだサンプリングされていませんか?メモリは小さいですが、マップのサイズも小さく、ああ、私はどのように行うには、この絵を描くためのキャンバスを使用しているのですか?もちろん、マトリックスと

Matrix matrix = new Matrix();
matrix.preScale(2, 2, 0, 0);
canvas.drawBitmap(bitmap, matrix, paint);

このように、数字は増幅効果の後に描かれているが、それはまだ私達のサンプルサイズのうちのメモリによって占有されています。私はそれらの写真を入れたい場合は、それをImageViewの?あなたが見ることができるように。

Matrix matrix = new Matrix();
matrix.postScale(2, 2, 0, 0);
imageView.setImageMatrix(matrix);
imageView.setScaleType(ScaleType.MATRIX);
imageView.setImageBitmap(bitmap);

ピクセルフォーマットの合理的な選択ビットマップ

実際には、我々はすでに、この問題の前で何度か言及しています。ARGB8888形式の画像は、各画素が4バイトを占め、RGB565は2バイトです。私たちは、フォーマットの多くの種類が利用可能であるかを見てみましょう。

フォーマット説明
ALPHA_8:唯一のアルファチャンネル
ARGB_4444:開始からこのAPI 13が悪いため、品質の推奨されない
ARGB_8888:ARGB 4つのチャネル、各チャネルの8ビット
RGB_565:各ピクセルは赤5ビットを占めて2バイトを占め、グリーンアカウンティング6ビット、青占めた5ビット

これらのうち、ALPHA8使用する必要はありません、我々はあなたが扱うことができるものは何でも色使用しているため。ARGB4444メモリ専用ARGB8888半分が、しかし、好意から、公式の心となっています。「メモリだけでなく、地域を占め、だけでなく、クールに見え、ChenqieはTTああやります。」ARGB8888が最も一般的で、それが最も精通している必要があります。RGB565私は、どこでもこの緑の資源の最適配分を見て、これを参照してください。特にリソース自体でケース(ダイに、突然良い悪のXD)、実際には、そうでない場合は、アルファチャンネル、JPG形式として、このフォーマットを使用するには理想的です。

26.ビューアニメーションの実行、View.clearAnimationを呼び出すには()のリソースを解放します。

さて、ここで終わりにする資料では、記事がかなり便利に感じる場合は、あなたの友人にそれをお勧めしたいことがあります。

おすすめ

転載: blog.51cto.com/14332859/2448606