Android性能优化之提升应用的启动速度

1.应用启动的两种方式

  • 冷启动:当直接从桌面上直接启动,同时后台没有该进程的缓存,这个时候系统就需要,重新创建一个新的进程并且分配各种资源。
  • 热启动:该app后台有该进程的缓存,这时候启动的进程就属于热启动。
    热启动不需要重新分配进程,直接走的就是app的Activity,这样就速度快很多

2.如何测量一个应用的启动时间
在命令行窗口使用命令行来启动app,同时进行时间测量。单位:毫秒
adb shell am start -W [PackageName]/[PackageName.MainActivity]

接着命令行窗口会返回下面两个数据:
ThisTime: 指当前指定的MainActivity的启动时间
TotalTime: 整个应用的启动时间,Application+Activity的使用的时间。

3.应用启动的流程
Application从构造方法开始—>attachBaseContext()—>onCreate()
Activity构造方法—>onCreate()<设置显示界面布局,设置主题、背景等等属性>—>onStart()—>onResume()<显示里面的view(测量、布局、绘制,显示到界面上)>

4.减少应用的启动时间的耗时

  • 不要在Application的构造方法、attachBaseContext()、onCreate()里面进行初始化耗时操作。
  • MainActivity,由于用户只关心最后的显示的这一帧,在写自定义控件的时候布局的层次要尽量减小。不要在onCreate、onStart、onResume当中做耗时操作。
  • 对于SharedPreference的初始化。
    因为他初始化的时候是需要将数据全部读取出来放到内存当中。
    优化1:可以尽可能减少sp文件数量(IO需要时间);2.像这样的初始化最好放到线程里面;3.大的数据缓存到数据库里面。

app启动的耗时主要是在:Application初始化(没多大办法改善重点在MainActivity界面的绘制上) + MainActivity的界面加载绘制时间。

viewStub的设计就是为了防止MainActivity的启动加载资源太耗时了。延迟进行加载,不影响启动,用户友好。

代码实现

  • MainActivity:
package com.example.aaa;

import java.lang.ref.WeakReference;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.ViewStub;
import android.widget.ProgressBar;

public class MainActivity extends FragmentActivity {
	private Handler mHandler = new Handler();
	private ViewStub viewStub;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		final SplashFragment splashFragment = new SplashFragment();
		final FragmentTransaction transaction = getSupportFragmentManager()
				.beginTransaction();
		transaction.replace(R.id.frame, splashFragment);
		transaction.commit();
		viewStub = (ViewStub) findViewById(R.id.content_viewstub);
		// 1.等整个界面加载完毕后,立马再加载真正的布局进来
		getWindow().getDecorView().post(new Runnable() {

			@Override
			public void run() {
				mHandler.post(new Runnable() {

					@Override
					public void run() {
						viewStub.inflate();
					}
				});
			}
		});
		// 2.延迟一段时间做动画,然后把splashfragment移除
		getWindow().getDecorView().post(new Runnable() {
			@Override
			public void run() {
				mHandler.postDelayed(new DelayRunnable(MainActivity.this,
						splashFragment), 2500);
			}
		});
		//3.同时异步预加载数据。
		//....
	}

	static class DelayRunnable implements Runnable {
		private WeakReference<Context> contextRef;
		private WeakReference<SplashFragment> fragmentRef;

		public DelayRunnable(Context context, SplashFragment splashFragment) {
			contextRef = new WeakReference<Context>(context);
			fragmentRef = new WeakReference<SplashFragment>(splashFragment);
		}

		@Override
		public void run() {
			FragmentActivity context = (FragmentActivity) contextRef.get();
			if (context != null) {
				SplashFragment splashFragment = fragmentRef.get();
				if (splashFragment == null)
					return;
				final FragmentTransaction transaction = context
						.getSupportFragmentManager().beginTransaction();
				transaction.remove(splashFragment);
				transaction.commit();
			}
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mHandler.removeCallbacksAndMessages(null);
	}
}
  • SplashFragment:
package com.example.aaa;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class SplashFragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater,
			 ViewGroup container, Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		return inflater.inflate(R.layout.fragment_splash, container, false);
	}
}

布局文件

  • activity_main:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ViewStub
        android:id="@+id/content_viewstub"
        android:layout="@layout/main_viewstub"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <FrameLayout
        android:id="@+id/frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>
</RelativeLayout>
  • fragment_splash:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.applicationstartoptimizedemo.MainActivity" >

    <FrameLayout
        android:id="@+id/frame"
        android:background="@drawable/splash12"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>

</RelativeLayout>
  • main_viewstub:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.applicationstartoptimizedemo.MainActivity" >

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitStart"
        android:src="@drawable/content" />
</RelativeLayout>
发布了61 篇原创文章 · 获赞 0 · 访问量 887

猜你喜欢

转载自blog.csdn.net/qq_36828822/article/details/103712159