알리 안드로이드 (26)이 Tiao 사양 및 최적화 경험

알리 안드로이드 (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 시간이 소요되는 작업이있는 경우 IntentService이 완료 만들어야합니다,) 시간이 많이 걸리는 작업을 브로드 캐스트 리시버 # onReceive를 (피하기 위해 및 브로드 캐스트 리시버에서 할 자식 스레드를 만들 것이다.

설명 :

방법은 메인 스레드에서 실행되기 때문에 시간이 많이 걸리는 작업이 원인이 경우 UI가 원활하지 않습니다. 당신은 IntentService를 사용 HandlerThread을 만들거나 # registerReceiver 컨텍스트 호출 할 수있는
다른 Wroker onReceive 스레드에서 방법을 수행하는 (브로드 캐스트 리시버,로 IntentFilter, 문자열, 핸들러) 방법 등. 브로드 캐스트 리시버 # onReceive ()에있어서 10 초 이상 걸리는 시스템 사망 할 수도

4 내재적 의도 방송 민감한 정보의 사용을 피하고, 다른 등록 정보가 대응 될 수있다
된 브로드 캐스트를 수신하는 앱.

설명 :

() 암시 적으로 방송 텐트 및 기타 위험한 작업에 전달 중요한 정보를 얻을 수있는 방송 수신기를 듣고 등록 된 모든 관심이 악성 응용 프로그램은 수신기 컨텍스트 번호를 통해 sendBroadcast받을 수 있습니다. 방송 순서를 전송 컨텍스트 # sendOrderedBroadcast () 메소드를 사용하여 브로드 캐스트 송신보다 높은 우선 순위가 악성 수신기 폐기 될 수있는 경우, 상기 방송 서비스를 이용할 수없는 결과는 악성 또는 방송 결과 데이터를 채우고있다. 방송이 응용 프로그램 내에서 제한되어있는 경우, 당신은 민감한 정보의 누출 및 의도 차단의 위험을 방지하기 위해, LocalBroadcastManager # sendBroadcast () 구현을 사용할 수 있습니다

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

타이밍들의 OnDestroy ()가 나중에 수행 할 수 있기 때문에 5, 활동 #들의 OnDestroy ()에서 작업 릴리스 자원을 수행하고, 같은 스레드와 같은 일부 작업의 파괴를 중지하지 않습니다. 실제 필요에 따라 액티비티 # onPause에서 isFinishing ()를 결정하는 단계와 함께 수행 () / 중지시 ().

6 등 비 필수로, 중첩 된 조각의 사용을 방지 할 수 있습니다.

설명 :

다음과 같이 안드로이드 API (17)에 중첩 조각이 SDK에 추가 라이브러리 기능을 지원한다, 조각 둥지 버그하는 경향이 일부 구덩이가있을 것입니다, 더 일반적인 문제가 요약되어 있습니다 :

1)하여 onActivityResult 장애 () 처리 방법, 내장 단편 콜백 메소드를 수신하지 않을 수도
단편 전달할 호스트에 의해 처리 될 필요
, 2) 돌연변이 애니메이션
조각의 재구성 결과, 3) 유전 setRetainInstance () 여러 트리거 불필요한 로직.

중첩 된 조각의 사용을 피하기 위해 가능한 한만큼 중요하지 않은 장면, 제발 참고 그 위에 언급 한 문제의 사용.

7, 현재 페이지 사이의 점프의 효율성에 영향을 미칠 것이다, 방법은 시간이 많이 걸리는 작업에 적합하지 않습니다 onPause 있도록 활동 onPause 메서드의 종료 후 실행 활동에서 onCreate 방법 옆에 수행됩니다

8, 안드로이드의 응용 프로그램 개체에 캐시하지 데이터를 않습니다. 베이스 성분 의도 이용 다른 메커니즘 간의 데이터 공유는 또한기구 된 SharedPreferences 지속성 데이터처럼 사용될 수있다

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

토스트를 사용하는 경우 (9), 토스트 (Toast.makeText의 사용을 피하고, 당신은 지속적인 팝업 토스트가있는 경우) 메시지가 계속 표시되면 토스트 토스트 취소 할 수 없을 때 상황을 피하기 위해 전역 객체를 정의하는 것이 좋습니다

10시 어댑터의 사용, 당신은 ViewHolder를 사용하는 경우는 null를 할 수와 같은 텍스트 텍스트 뷰 세트로에 관계없이 각 자식 컨트롤 요구의 convertView이 특성을 (설정 여부의 캐싱, 메소드의 getView ()를 수행합니다 버튼 배경색이 명시 적으로 설정된 속성에 투명 투명한 제어 등), 필요로,도) 투명한 배경을 설정하거나 슬라이딩하는 과정에서 (텍스트 텍스트 뷰가 비어도 세트의 setText는 ( ""입니다) 어댑터 항목을 다중화, 내용이있을 것이기 때문에, 혼란을 표시

활동 또는 단편 동적 브로드 캐스트 리시버, registerReceiver () 및 unregisterReceiver 등록 할 때 (11)는 () 페어링한다.

설명 :

registerReceiver ()와 unregisterReceiver ()는 메모리 누수로 이어지는, 이미 적절한시기에 상각 등록되지 않은 수신기가 발생할 수 있습니다 표시하지 않을 경우, 메모리 공간은 시스템 서비스 부담을 증가 점령했다.

자원 관리 및 제어 수신기 것이다 화웨이의 모델의 일부는, 하나의 등록 신청은 과도한 수신기 제어 모듈은 예외, 충돌에 직접 응용 프로그램을 던졌습니다 트리거합니다.

레이아웃이있는 LinearLayout은 찬성 RelativeLayout의 중첩 사용하지 않는 여러 중첩 된 뷰 그룹을 사용했을 때 (12)는, 효과적으로 중첩의 수를 줄일 수 있습니다.

설명 :

뷰 페이지에 안드로이드 응용 프로그램은, 어떠한 조치, 레이아웃을 통과 올바르게 렌더링하기 위해 세 단계를 그릴 수 있습니다. 측정을 시작하는 XML 레이아웃의 상단 노드에서 각 아이는이 과정에서 또 다시 측정 할 수있다, 부모 노드에 쇼의 위치를 ​​결정하기 위해 자신의 크기를 제공하는 소모 원래 시간을 측정 될 수 있습니다 (이 필요합니다 2 ~ 3 회). 노드의 깊이 위치, 더 중첩 된 가져 측정, 계산은 더 많은 시간이 소요됩니다. 평면 뷰 구조 성능이 더 나은 이유입니다.

또한, 더 많은 페이지보기에 개최 시간 측정 긴, 레이아웃, 무승부합니다. 이 시간을 단축하기 위해, 키는 가능한 트리 구조보기 평면을 유지하고, 불필요한 렌더링보기를 제거하는 것입니다. 이상적으로는, 측정, 레이아웃의 전체가 매끄러운 슬라이딩 UI 화면을 보장하기 위해 시간이 16ms보다 잘 제어되어야 그린다.

그 여분의보기 (증가 렌더링 지연보기) 찾으려면 Hierarachy 뷰어 도구, 시각적으로보기보기에서 안드로이드 스튜디오 모니터를 사용할 수 있습니다

대화 상자 또는 팝업 디스플레이 담요, 오히려 활동에 비해 DialogFragment의 사용을 만들 수 (13),
대화 /에 AlertDialog를, 그것은 활동 수명주기 관리 대화 상자 / 팝 라이프 사이클 부동 층으로 쉽게

14, 텍스트 크기, 단위 DP를 이용 유닛 (DP)의 사용의 크기보기. 텍스트 뷰를 들어, 피할 텍스트 디스플레이 어댑터 문제에 대한 텍스트의 크기를 결정하는 경우에 권장 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;
}

17 SharedPreference는 편집기 #의 메이크업 사용에 데이터를 제출 ()를 적용, 에디터 # 커밋보다는 (). 일반적으로 만 때 결과를 제출하는 방법을 결정해야하고 그에 따라 전용 () 편집기 # 커밋 사용하여 후속 작업이 있습니다.

설명 :

SharedPreference 관련 개정안은이 방법은 메모리에 먼저 쓰기를 의지하고 비동기 적으로 디스크에 기록 적용 디스크에 직접 기록 방법을 커밋하여 제출. 자주 작동하면, 디스크에 기록 된 내용을 마지막으로 수정됩니다 적용, 성능이 더 좋은 커밋보다 것이다 적용됩니다. 즉시 그에 따라 결과 저장 작업 및 기타 작업을 얻으려면, 당신은 커밋 사용해야합니다.

18, 데이터베이스 커서 확인해야 순서 가까운 메모리 누출을 피하기 위해 그 이후.
멀티 스레드 작업이 데이터베이스에, 당신은 피할 동기화 문제에 대한 트랜잭션을 사용해야합니다.
SQL 문을 실행할 때, 당신의 SQLiteDatabase # 삽입 (), 업데이트 (사용해야합니다 ) (삭제) SQL 인젝션의 위험을 방지하기 위해의 SQLiteDatabase #에는 ExecSQL ()를 사용하지 마십시오

19, 대형 포토 또는 일회용 로딩 여러 이미지를로드, 이는 비동기 스레드에서 수행되어야한다. IO 작업 및 CPU 집약적 인 작업과 관련된 부하의 사진은, 그것은 가능성이 Caton의 원인이다.

20의 ListView, ViewPager, RecyclerView, GirdView 및 다른 구성 요소의 이미지의 사용은 캐시의 이미지로 제조되어야 할 때, 항상 방지하는 화상 메모리 누수를 보유하고, 또한 피 복제의 성능 문제를 일으키는 화상을 생성한다. 권장 프레스코 (https://github.com/facebook/fresco ) 글라이드 (https://github.com/bumptech/glide ) 등 포토 갤러리

압축 공정 tinypng 또는 유사한 공구를 사용하여 이미지를 PNG로 (21), 포장 부피를 줄일

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를 사용할 수 없다는 것을 유의해야한다

피카소 ARGB_8888 기본 형식이며, 상기 메모리는 오버 헤드가 작아 반 동안 1) 글라이드 비트 맵 형식의 기본 형식 RGB_565가있다
디스크 캐시 환산 2)에 캐시 할 픽처의 피카소 원래 크기 글라이드 캐시 다양한 사양 인 반면, 이는 글라이드는 당신의 이미지 뷰의 크기가, 아트 워크는 400,400이며, 200,200 글라이드지도 사양을 캐시하여 200,200이며 피카소의 사양 전용 캐시 400,400로 이미지 뷰 이미지 크기 적절한 크기의 크기에 따라 캐시됩니다 의미 . 이러한 개선은 덜 다시 렌더링 과정을 각각 잘라 내기, 결국, 빠른 로딩 피카소의 속도보다 글라이드으로 이어질 것입니다.
3) 가장 중요한 기능은 글라이드 지프 동적 부하지도를 지원하고, 피카소는이 기능을 지원하지 않습니다.

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;
}

사용 매트릭스

작은, 작은 매트릭스 대용으로도 큰 샘플.

또는 위의 예 퍼지 사진을 사용, 우리는 아직 샘플링되지 않습니다? 메모리는 작지만,지도의 크기도 작고, 아, 내가 어떻게 할 방법이 그림을 그리는 캔버스를 사용입니까? 매트릭스와 과정,의

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

이와 같이, 도면은 증폭 효과 후 인출되지만 여전히 우리의 샘플 크기 점 메모리에 의해 점유된다. 나는 그 사진을 넣어하려는 경우 그것을 이미지 뷰? 당신이 볼 수 있듯이 :

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 네 채널, 각 채널의 8 비트
RGB_565을 각 픽셀은 빨간색 5 비트를 차지 2 바이트를 차지, 녹색 회계 6 비트, 파란색 차지 5 비트

이 중, ALPHA8 사용할 필요, 우리는 당신이 처리 할 수있는 어떤 색상을 사용하기 때문에. ARGB4444 메모리 전용 ARGB8888 반하지만,하지만, 호의, 공식 마음이었다. . "메모리뿐만 아니라 지방을 차지, 또한 멋진 모습, Chenqie는 TT 아 않는다"고 말했다. ARGB8888 가장 일반적인, 그것은 가장 잘 알고 있어야합니다. RGB565 나는 사방이 녹색 자원의 최적 배분을 보았다,이를 참조하십시오. . 케이스는이 형식이 적합 사용, 특히 JPG 형식으로 자원 자체에, 그렇지 않은 경우 알파 채널, 사실, (갑자기 좋은 악한 XD, 죽을).

(26)보기 애니메이션 실행, View.clearAnimation를 호출 ()가 리소스를 해제합니다.

당신이 문서는 매우 유용 느낀다면 글쎄, 기사 친구에게 추천 할 수 있습니다, 여기에 종료합니다.

추천

출처blog.51cto.com/14332859/2448606