目录
需求怎么来的
项目中处理新进程的冷启动,之前一直是通过一下方式去设置的,一张启动页面的图片设置为window的背景,但是这种方式最近被我们领导吐槽了...
<style name="AppTheme.Launcher.Main" parent="@style/AppTheme">
<item name="android:windowBackground">@drawable/load</item>
</style>
<activity
android:name=".activity.hi_school.HiSchoolDetailsActivity"
android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
android:label="@string/app_name"
android:maxAspectRatio="2.4"
android:process="other process name"//新的进程Id
android:screenOrientation="portrait"
android:theme="@style/AppTheme.Launcher.Main" />
中间间隔三四秒的停顿显示着那张启动页,确实让人很难受,用户有时候还以为项目卡死了。既然这样,那让我们动起来,kill掉这个“BUG”。
换一个思路去实现
既然这样不行,那我们就换一个思路去实现吧,比如上面的那个android:windowBackground 后面设置一个动图?或着想办法让window透明?
动图
这里先给大家说一个不好的消息android:windowBackground 不支持动图 ,也就是说放一张GIF的图片 也没用,至于其他的动图方法,只能说进程都没初始化完呢,何必给它在增加这些负担,那就试试另一个思路吧。
透明背景
首先设置两个style:
<style name="ThemeLauncher" parent="@style/AppTheme">
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="ThemeLauncherChange" parent="@style/AppTheme">
<item name="android:windowBackground">@color/white</item>
<item name="android:windowIsTranslucent">false</item>
</style>
为什么是两个? 这里提前给大家打一个预防针,在低版本的手机中如果window为透明的话,会报错哦,表面来看就是新的界面没有启动,那是因为新的进程直接崩溃了。
那我们 透明背景的思路 怎么去实现呢,继续往下看吧!
把AndroidManifest.xml中,新进程第一个启动的activity的android:theme="@style/AppTheme.Launcher.Main"替换成android:theme="@style/ThemeLauncher"
到这一步,启动的时候已经可以实现透明背景了,不用让用户看着那个黑屏、白屏、静态启动图发呆了。但是说好的崩溃呢,怎么处理?哦对了,报错的位置会指向 super.onCreate(Bundle saveInstanceState);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
}
可以很开心的告诉大家 既然是这一行报错,那我们就在他前面把背景改过来呗!请收下修改后的代码
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.ThemeLauncherChange);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hsxiu_chang_details);
}
嘿嘿,既然已经解决黑白屏问题了,启动图也不用了,那总不能让用户点击按钮之后的两三秒一直没动静吧!
请继续往下看 ⬇️
显示Loading来提示用户手机正在反应
这个时候会遇到两个问题,什么时候去展示Loading,什么时候去取消loading?
显示Loading 最简单不过了,按钮点击的时候展示就是,比如在当前的Activity 写一个方法
public class HiSchoolDetailsActivity extends Activity{
public static void startToHSXiuChangDetailsActivity(Context context) {
Intent intent = new Intent(context, HiSchoolDetailsActivity.class);
context.startActivity(intent);
load(context);
}
}
public static void load(Context context) {
LoadUtil loadUtil = new LoadUtil(context, LoadUtil.LOAD_DEFULT);
loadUtil.showLoading();
new StartNewProcessSucess(context) {
@Override
public void operation() {
loadUtil.highLoading();
}
};
}
StartNewProcessSucess 是一个广播,我这里起名不太标准。
/**
* @author: jjf
* @date: 2020/8/25
* @describe: 创建自动注册广播,只接受一个广播,接受消息之后自动解除注册
*/
public abstract class StartNewProcessSucess extends BroadcastReceiver {
Context context;
public StartNewProcessSucess(Context context) {
this.context = context;
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConstantsOfBroadcastAction.START_NEW_PROCESS_SUCCESS);
context.registerReceiver(this, intentFilter);
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null) {
if (ConstantsOfBroadcastAction.START_NEW_PROCESS_SUCCESS.equals(action)) {
operation();
context.unregisterReceiver(this);
}
}
}
public abstract void operation();
}
以上是大部分的代码了,能看到这里 展示 隐藏loading 代码就是上面这些了,但是你没发现少点代码吗?嘿嘿
这个广播什么时候发送呢?当然是新界面启动之后去发送广播取消Loading 呀,什么时机最合适呢?你肯定会想到onCreate,但是onCreate执行的时候,是进程创建好之后 ,界面开始创建的时候在这里面去掉loading会有短暂的空白期,所以在onResume!中发送广播最合适。