Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit265c803

Browse files
author
lanxiaobin
committed
今日头条 MultiDex 启动优化
0 parents  commit265c803

File tree

35 files changed

+1009
-0
lines changed

35 files changed

+1009
-0
lines changed

‎.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea/caches
5+
/.idea/libraries
6+
/.idea/modules.xml
7+
/.idea/workspace.xml
8+
/.idea/navEditor.xml
9+
/.idea/assetWizardSettings.xml
10+
.DS_Store
11+
/build
12+
/captures
13+
.externalNativeBuild
14+
.cxx

‎app/build.gradle

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
applyplugin:'com.android.application'
2+
3+
android {
4+
compileSdkVersion 28
5+
defaultConfig {
6+
applicationId"com.lanshifu.multidextest"
7+
minSdkVersion15
8+
targetSdkVersion28
9+
versionCode1
10+
versionName"1.0"
11+
testInstrumentationRunner"androidx.test.runner.AndroidJUnitRunner"
12+
13+
defaultConfig {
14+
//分包1,指定某个类在maindex,例如LeakCanary启动的时候会初始化一个ContentProvider
15+
multiDexEnabledtrue
16+
multiDexKeepProguard file('multiDexKeep.pro')// 打包到main dex的这些类的混淆规制,没特殊需求就给个空文件
17+
multiDexKeepFile file('maindexlist.txt')// keep specific classes
18+
}
19+
}
20+
buildTypes {
21+
release {
22+
minifyEnabledfalse
23+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
24+
}
25+
}
26+
}
27+
28+
dependencies {
29+
implementation fileTree(dir:'libs',include: ['*.jar'])
30+
implementation'androidx.appcompat:appcompat:1.0.2'
31+
implementation'androidx.constraintlayout:constraintlayout:1.1.3'
32+
testImplementation'junit:junit:4.12'
33+
androidTestImplementation'androidx.test:runner:1.1.1'
34+
androidTestImplementation'androidx.test.espresso:espresso-core:3.1.1'
35+
36+
implementation'androidx.multidex:multidex:2.0.0'
37+
}

‎app/maindexlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com/lanshifu/launchtest/LoadMultiDexActivity.class

‎app/multiDexKeep.pro

Whitespace-only changes.

‎app/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile

‎app/src/main/AndroidManifest.xml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.lanshifu.launchtest">
4+
5+
<application
6+
android:name="com.lanshifu.launchtest.MyApplication"
7+
android:allowBackup="true"
8+
android:icon="@mipmap/ic_launcher"
9+
android:label="@string/app_name"
10+
android:roundIcon="@mipmap/ic_launcher_round"
11+
android:supportsRtl="true"
12+
android:theme="@style/AppThemeWelcome">
13+
<activityandroid:name="com.lanshifu.launchtest.LoadMultiDexActivity"
14+
android:process=":multi_dex"
15+
android:launchMode="singleTask"
16+
android:excludeFromRecents="true"
17+
></activity>
18+
<activityandroid:name="com.lanshifu.launchtest.MainActivity" />
19+
<activityandroid:name="com.lanshifu.launchtest.SplashActivity">
20+
<intent-filter>
21+
<actionandroid:name="android.intent.action.MAIN" />
22+
23+
<categoryandroid:name="android.intent.category.LAUNCHER" />
24+
</intent-filter>
25+
</activity>
26+
</application>
27+
28+
</manifest>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
packagecom.lanshifu.launchtest;
2+
3+
importandroid.app.Activity;
4+
importandroid.app.AlertDialog;
5+
importandroid.content.Context;
6+
importandroid.os.Bundle;
7+
importandroid.os.Process;
8+
importandroid.util.Log;
9+
10+
importandroidx.multidex.MultiDex;
11+
12+
importjava.io.File;
13+
14+
publicclassLoadMultiDexActivityextendsActivity {
15+
privatestaticfinalStringTAG ="lxb-LoadMultiDexActivity";
16+
17+
@Override
18+
protectedvoidonCreate(BundlesavedInstanceState) {
19+
super.onCreate(savedInstanceState);
20+
setContentView(R.layout.activity_load_multi_dex);
21+
22+
23+
Threadthread =newThread() {
24+
@Override
25+
publicvoidrun() {
26+
27+
loadMultiDex();
28+
}
29+
};
30+
thread.setName("multi_dex");
31+
thread.start();
32+
33+
showLoadingDialog();
34+
}
35+
36+
37+
privatevoidloadMultiDex(){
38+
Log.d(TAG,"MultiDex.install 开始: ");
39+
longstartTime =System.currentTimeMillis();
40+
MultiDex.install(LoadMultiDexActivity.this);
41+
Log.d(TAG,"MultiDex.install 结束,耗时: " + (System.currentTimeMillis() -startTime));
42+
43+
try {
44+
//模拟MultiDex耗时很久的情况
45+
Thread.sleep(3000);
46+
}catch (InterruptedExceptione) {
47+
e.printStackTrace();
48+
}
49+
50+
51+
aftetMultiDex();
52+
}
53+
54+
privatevoidaftetMultiDex() {
55+
56+
deleteTempFile(this);
57+
58+
//将这个进程杀死
59+
Log.d(TAG,"aftetMultiDex: ");
60+
finish();
61+
Process.killProcess(Process.myPid());
62+
}
63+
64+
privatevoiddeleteTempFile(Contextcontext) {
65+
try {
66+
Filefile =newFile(context.getCacheDir().getAbsolutePath(),"load_dex.tmp");
67+
if (file.exists()) {
68+
file.delete();
69+
Log.d(TAG,"deleteTempFile: ");
70+
}
71+
}catch (Throwableth) {
72+
th.printStackTrace();
73+
}
74+
}
75+
76+
privatevoidshowLoadingDialog(){
77+
newAlertDialog.Builder(this)
78+
.setMessage("加载中,请稍后...")
79+
.show();
80+
}
81+
82+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
packagecom.lanshifu.launchtest;
2+
3+
importandroidx.appcompat.app.AppCompatActivity;
4+
5+
importandroid.os.Bundle;
6+
7+
publicclassMainActivityextendsAppCompatActivity {
8+
9+
@Override
10+
protectedvoidonCreate(BundlesavedInstanceState) {
11+
setTheme(R.style.AppTheme);
12+
super.onCreate(savedInstanceState);
13+
setContentView(R.layout.activity_main);
14+
15+
setTitle("主页");
16+
}
17+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
packagecom.lanshifu.launchtest;
2+
3+
importandroid.app.Application;
4+
importandroid.content.Context;
5+
importandroid.content.Intent;
6+
importandroid.util.Log;
7+
8+
importandroidx.multidex.MultiDex;
9+
10+
importcom.lanshifu.launchtest.ustils.SystemUtil;
11+
12+
importjava.io.File;
13+
14+
publicclassMyApplicationextendsApplication {
15+
privatestaticfinalStringTAG ="lxb-MyApplication";
16+
17+
@Override
18+
protectedvoidattachBaseContext(Contextbase) {
19+
super.attachBaseContext(base);
20+
21+
Log.d(TAG,"attachBaseContext-getPackageName: " +base.getPackageName());
22+
Log.d(TAG,"attachBaseContext-getProcessName: " +SystemUtil.getProcessName(base));
23+
24+
25+
booleanisMainProcess =isMainProcess(base);
26+
Log.d(TAG,"attachBaseContext-isMainProcess: " +isMainProcess);
27+
28+
//主进程并且vm不支持多dex的情况下才使用 MultiDex
29+
if (isMainProcess && !SystemUtil.isVMMultidexCapable()){
30+
loadMultiDex(base);
31+
}
32+
33+
}
34+
35+
privatebooleanisMainProcess(Contextcontext) {
36+
returncontext.getPackageName().equals(SystemUtil.getProcessName(context));
37+
}
38+
39+
@Override
40+
publicvoidonCreate() {
41+
super.onCreate();
42+
if (!isMainProcess(this)){
43+
Log.d(TAG,"onCreate: 非主进程,return");
44+
return;
45+
}
46+
47+
Log.d(TAG,"主进程 onCreate: 一些初始化操作");
48+
49+
}
50+
51+
52+
privatevoidloadMultiDex(Contextcontext) {
53+
newTempFile(context);//创建临时文件
54+
55+
//启动另一个进程去加载MultiDex
56+
Intentintent =newIntent(context,LoadMultiDexActivity.class);
57+
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
58+
context.startActivity(intent);
59+
60+
//检查MultiDex是否安装完(安装完会删除临时文件)
61+
checkUntilLoadDexSuccess(context);
62+
63+
//另一个进程以及加载 MultiDex,有缓存了,所以主进程再加载就很快了。
64+
//为什么主进程要再加载,因为每个进程都有一个ClassLoader
65+
longstartTime =System.currentTimeMillis();
66+
MultiDex.install(context);
67+
Log.d(TAG,"第二次 MultiDex.install 结束,耗时: " + (System.currentTimeMillis() -startTime));
68+
}
69+
70+
71+
//创建一个临时文件,MultiDex install 成功后删除
72+
privatevoidnewTempFile(Contextcontext) {
73+
try {
74+
Filefile =newFile(context.getCacheDir().getAbsolutePath(),"load_dex.tmp");
75+
if (!file.exists()) {
76+
Log.d(TAG,"newTempFile: ");
77+
file.createNewFile();
78+
}
79+
}catch (Throwableth) {
80+
th.printStackTrace();
81+
}
82+
}
83+
84+
/**
85+
* 检查MultiDex是否安装完,通过判断临时文件是否被删除
86+
* @param context
87+
* @return
88+
*/
89+
privatevoidcheckUntilLoadDexSuccess(Contextcontext) {
90+
Filefile =newFile(context.getCacheDir().getAbsolutePath(),"load_dex.tmp");
91+
inti =0;
92+
intwaitTime =100;//睡眠时间
93+
try {
94+
Log.d(TAG,"checkUntilLoadDexSuccess: >>> ");
95+
while (file.exists()) {
96+
Thread.sleep(waitTime);
97+
Log.d(TAG,"checkUntilLoadDexSuccess: sleep count = " + ++i);
98+
if (i >40) {
99+
Log.d(TAG,"checkUntilLoadDexSuccess: 超时,等待时间: " + (waitTime *i));
100+
break;
101+
}
102+
}
103+
104+
Log.d(TAG,"checkUntilLoadDexSuccess: 轮循结束,等待时间 " +(waitTime *i));
105+
106+
}catch (Exceptione){
107+
e.printStackTrace();
108+
}
109+
110+
}
111+
112+
113+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
packagecom.lanshifu.launchtest;
2+
3+
importandroid.content.Intent;
4+
importandroid.os.Bundle;
5+
importandroid.view.View;
6+
importandroid.widget.Button;
7+
8+
importandroidx.appcompat.app.AppCompatActivity;
9+
10+
publicclassSplashActivityextendsAppCompatActivity {
11+
12+
@Override
13+
protectedvoidonCreate(BundlesavedInstanceState) {
14+
setTheme(R.style.AppTheme);
15+
super.onCreate(savedInstanceState);
16+
setTitle("闪屏页");
17+
setContentView(R.layout.activity_splash);
18+
19+
Buttonbutton =findViewById(R.id.button);
20+
View.OnClickListeneronClickListener =newView.OnClickListener() {
21+
@Override
22+
publicvoidonClick(Viewv) {
23+
startActivity(newIntent(SplashActivity.this,MainActivity.class));
24+
}
25+
};
26+
button.setOnClickListener(onClickListener);
27+
}
28+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp