在当今激烈竞赛的移动运用商场,运用的发动速度直接影响着用户的第一印象和满意度。作为主流的移动操作系统之一,Android的发动优化是开发者必须关注的要害领域。本文将具体介绍一些强壮有用的Android发动优化战略,协助你优化运用的发动过程,为用户创造更超卓的体会。

冷发动与热发动

在着手优化之前,让我们深入了解Android运用的发动过程。Android运用的发动可分为冷发动和热发动两种情况。冷发动是指运用从彻底关闭状况发动,而热发动则是从后台状况重新发动运用。尽管热发动也重要,但优化冷发动对进步用户体会影响更为明显,因为它需求加载更多资源和组件。

布局优化

运用发动时,系统需求加载布局资源并构建视图层级。因此,布局优化是进步发动速度的要害所在。

运用ConstraintLayout进行灵活布局

ConstraintLayout是一种强壮且高效的布局办法,可以下降嵌套层级,然后进步布局功用。它经过界说束缚联系来定位视图,削减了传统布局中频频的测量和布局操作。

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <!-- 在此增加你的UI元素 -->
</androidx.constraintlayout.widget.ConstraintLayout>

运用ViewStub完成推迟加载

ViewStub是Android供给的一个特殊视图,充当占位符,在需求显现其内容时才会实例化和加载。在布局中运用ViewStub可以有用推迟加载视图,然后加快发动时刻。

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 其他UI元素 -->
    <ViewStub
        android:id="@+id/myViewStub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/my_delayed_layout" />
</RelativeLayout>

其间@layout/my_delayed_layout是要推迟加载的布局资源的引证。

在需求显现ViewStub内容的位置,调用ViewStub.inflate()办法加载实际的布局内容:

ViewStub myViewStub = findViewById(R.id.myViewStub);
View inflatedView = myViewStub.inflate();

通常情况下,你可以根据用户交互或其他条件来触发加载。总之,与将视图设置为android:visibility="gone"相比,运用ViewStub是更好的办法完成推迟加载,特别是在发动时需求进步功用的情况下。

发动时序优化

精密控制发动时序可以明显进步发动速度,以下是一些优化战略。

呈现引人注目的闪屏界面

引入闪屏界面(Splash Screen)可以在运用加载资源的一起显现品牌标志或加载动画,缓解发动过程中的等待感。

res/values/styles.xml 中界说款式:

<style name="AppTheme.Splash" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_background</item>
</style>

res/drawable 中创立 splash_background.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/splashBackgroundColor" />
    <item>
        <bitmap
            android:src="@drawable/app_logo"
            android:gravity="center" />
    </item>
</layer-list>

AndroidManifest.xml 中设置 Splash Screen 款式:

<activity
    android:name=".SplashActivity"
    android:theme="@style/AppTheme.Splash">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

下降主线程担负

主线程负责处理运用的UI操作,因此在发动过程中下降主线程作业量至关重要。

充分利用异步使命

经过将耗时使命转移到后台线程,避免了阻塞主线程。你可以运用 AsyncTaskViewModel 来办理数据和UI更新。

public class MyAsyncTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... voids) {
        // 履行耗时使命
        return null;
    }
    @Override
    protected void onPostExecute(Void aVoid) {
        // 更新UI或履行其他操作
    }
}

智能后台初始化

将发动所需的初始化作业一部分放到后台线程中处理,以更快地显现运用的核心界面。

public class StartupTask extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // 在后台线程中履行初始化作业
        new Thread(() -> {
            // 履行初始化作业
        }).start();
    }
}

优化运用资源加载

在运用发动过程中,资源的加载可能是影响发动速度的一个重要因素。优化资源加载可以明显削减发动时刻。

运用矢量图形资源

运用矢量图形资源(SVG、Vector Drawable)替代位图资源,可以减小APK的巨细,一起习惯不同屏幕密度的设备。

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/ic_vector_image" />

紧缩位图资源

运用工具如 TinyPNG 可以紧缩PNG和JPEG图片,减小APK的巨细。别的,确保供给各种密度的图片资源,以习惯不同屏幕的设备。

运用运用冷发动优化库

Android供给了一些优秀的发动优化库,可以协助你主动办理和削减发动时刻。

运用Hilt进行依靠注入

Hilt是Android官方供给的依靠注入库。经过运用Hilt,你可以将发动时创立的依靠联系移到后台,削减主线程上的作业。

// 界说依靠联系
@Module
@InstallIn(SingletonComponent.class)
public class MyModule {
    @Provides
    public MyDependency provideMyDependency() {
        return new MyDependency();
    }
}
// 在Application中初始化Hilt
@HiltAndroidApp
public class MyApp extends Application {
}

运用Jetpack Compose重构UI

Jetpack Compose是一款现代的UI工具包,可以协助你以声明性的办法构建界面。因为其功用优势,运用Compose可以进步运用的发动速度。

@Composable
fun MyScreen() {
    Column {
        Text(text = "Hello, Jetpack Compose!")
        Button(onClick = { /* Do something */ }) {
            Text(text = "Click me")
        }
    }
}

恰当运用多进程

将某些耗时的初始化作业放在独自的进程中进行,可以削减主进程的担负,然后进步运用的发动速度。

创立后台进程

在AndroidManifest.xml中界说一个后台进程:

<application
    android:name=".MyApplication"
    android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher"
    android:process=":background">
    <!-- ... -->
</application>

履行耗时使命

在后台进程中履行耗时使命,例如初始化某些模块或资源:

public class BackgroundProcessService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        // 在后台进程中履行耗时使命
        // ...
        stopSelf(); // 使命完成后中止服务
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

削减发动Activity的冷发动

Android的发动过程中,冷发动Activity的时刻占比较大。以下是一些削减冷发动Activity时刻的办法。

运用SingleTask发动模式

将冷发动Activity设置为SingleTask发动模式,可以在同一使命栈中复用已有的Activity实例,然后削减Activity的重复创立。

<activity
    android:name=".MainActivity"
    android:launchMode="singleTask">
</activity>

运用Splash Screen优化冷发动体会

在Splash Screen中履行一些初始化操作,如预加载数据,然后将部分冷发动时刻移至Splash Screen阶段。

public class SplashActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 履行初始化操作,如预加载数据
        // ...
        startActivity(new Intent(this, MainActivity.class));
        finish();
    }
}

借助第三方开源库

android-startup供给一种在运用发动时可以愈加简单、高效的办法来初始化组件。开发人员可以运用android-startup来简化发动序列,并显式地设置初始化顺序与组件之间的依靠联系。 与此一起android-startup支撑同步与异步等待,并经过有向无环图拓扑排序的办法来确保内部依靠组件的初始化顺序。

增加依靠

repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.github.idisfkj:android-startup:1.1.0'
}

界说初始化的组件

每一个初始化的组件都需求完成AndroidStartup抽象类,它完成了Startup接口
例如,下面界说一个SampleSecondStartup类来完成AndroidStartup抽象类:

class SampleSecondStartup : AndroidStartup<Boolean>() {
    override fun callCreateOnMainThread(): Boolean = false
    override fun waitOnMainThread(): Boolean = true
    override fun create(context: Context): Boolean {
        // 仿照履行耗时
        Thread.sleep(5000)
        return true
    }
    override fun dependenciesByName(): List<String> {
        return listOf("com.rousetime.sample.startup.SampleFirstStartup")
    }
}

在dependenciesByName()办法中返回了com.rousetime.sample.startup.SampleFirstStartup,所以它能确保SampleFirstStartup优先履行结束。

发动装备

供给两种装备,Manifiest中主动装备与Application中手动装备
下面给出主动装备示例:

<provider
    android:name="com.rousetime.android_startup.provider.StartupProvider"
    android:authorities="${applicationId}.android_startup"
    android:exported="false">
    <meta-data
        android:name="com.rousetime.sample.startup.SampleFourthStartup"
        android:value="android.startup" />
</provider>

在Android Startup中供给了StartupProvider类,它是一个特殊的content provider,供给主动识别在manifest中装备的初始化组件。 为了让其可以主动识别,需求在StartupProvider中界说标签。其间的name为界说的组件类,value的值对应为android.startup。

合理的办理发动使命,将会极大的进步运用的发动时刻,获得更佳的发动体会。

结论

经过优化运用资源加载、运用优秀的发动优化库、恰当运用多进程以及削减冷发动Activity的时刻,你可以进一步进步Android运用的发动速度,为用户创造更佳的发动体会。不同的优化战略可以相互协作,以达到更好的作用。

引荐

android_startup: 供给一种在运用发动时可以愈加简单、高效的办法来初始化组件,优化发动速度。不只支撑Jetpack App Startup的全部功用,还供给额定的同步与异步等待、线程控制与多进程支撑等功用。

AwesomeGithub: 根据Github的客户端,纯练习项目,支撑组件化开发,支撑账户密码与认证登陆。运用Kotlin言语进行开发,项目架构是根据JetPack&DataBinding的MVVM;项目中运用了Arouter、Retrofit、Coroutine、Glide、Dagger与Hilt等盛行开源技术。

flutter_github: 根据Flutter的跨平台版别Github客户端,与AwesomeGithub相对应。

android-api-analysis: 结合具体的Demo来全面解析Android相关的知识点, 协助读者可以更快的把握与了解所阐述的要点。

daily_algorithm: 每日一算法,由浅入深,欢迎参加一起共勉。