当初市面上很多app上都有小游戏(或叫h5游戏),它们借助小游戏来进步整个app的粘性。像微信app、趣头条app、哈啰app上曾经呈现了小游戏模块。

用户聊天、刷资讯、骑车之余能够关上小游戏劳动放松,如果忽然间来音讯了或者玩手游累了想看资讯,敞开游戏页面后,再次关上游戏是接着玩,不须要从新加载游戏。

如何实现这种成果呢?

咱们晓得activity敞开后,再次关上必定要走onCreate生命周期,那么页面相干资源就要重建,这样就得从新加载游戏了。

微信小游戏是如何做到,敞开activity后,再次关上会保留之前的资源和状态呢?

实际上,微信小游戏敞开activity关不是finish掉了,而且跳转到其它页面了,小游戏页面还在后盾运行,游戏也处于暂停状态,相干资源还在内存保留,没有被回收。再次关上同一个游戏,那么就不会再从新加载了。

那么这外面就波及两个问题。

第一个问题,从游戏页面返回上一个页面或者跳转到其它页面,如何保障指标页面不会重建呢?

这个很简略,把指标页面启动模式设置成SingleTask或者SingleTop就能够了:

  <activity         android:name="com.devnn.demo.MainActivity"         android:launchMode="singleTask">        <intent-filter>             <action android:name="android.intent.action.MAIN" />             <category android:name="android.intent.category.LAUNCHER" />        </intent-filter>   </activity>

或者在跳转的Intent上加上标记:clearTop或者singleTop也能达到同样的成果:

     Intent intent = new Intent(this, MainActivity.class);     intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);     //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);     startActivity(intent);

clearTop相似于SingleTask,是革除指标activity之上的activity来保障指标activity不重建,这个实用于回到主页面。
SginleTop是保障栈顶的activity惟一,这个实用于从一个栈跳转到另一个栈的栈顶页面。(请接着看第二个问题。)

第二个问题,再次回到游戏,如何保障游戏页面不会重建呢?

这个其实也波及到启动模式常识。将小游戏页面启动模式设置成SingleInstance即可。SingleInstance示意,将activity存在在独自的task栈中。那么两个栈中的页面来回切换就不便自若了。配置如下:

  <activity            android:name="com.devnn.demo.ActivityA"            android:launchMode="singleInstance">  </activity>

笔者做了一个demo实现了小游戏这种场景。其中MainActivity是主页面,ActivityA是仿小游戏页面。

MainActivity.java

package com.devnn.demo;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.view.View;public class MainActivity extends AppCompatActivity {    private String TAG="MainActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        Log.i(TAG,"onCreate");        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    @Override    protected void onResume() {        Log.i(TAG,"onResume");        super.onResume();    }    @Override    protected void onNewIntent(Intent intent) {        Log.i(TAG,"onNewIntent");        super.onNewIntent(intent);    }    public void toActivityA(View view) {        Intent intent = new Intent(this, ActivityA.class);        startActivity(intent);    }}

ActivityA.java

package com.devnn.demo;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.util.Log;public class ActivityA extends AppCompatActivity {    private String TAG = "ActivityA";    @Override    protected void onCreate(Bundle savedInstanceState) {        Log.i(TAG, "onCreate");        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_a);        Log.i(TAG, "onCreate_task_id="+getTaskId());    }    @Override    public void onBackPressed() {        Log.i(TAG, "onBackPressed");        Intent intent = new Intent(this, MainActivity.class);        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);        //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);        startActivity(intent);//        moveTaskToBack(true);//回到上一个工作栈,如果上一个工作栈是最近工作,就会回到桌面    }    @Override    protected void onNewIntent(Intent intent) {        Log.i(TAG, "onNewIntent");        super.onNewIntent(intent);    }    @Override    protected void onResume() {        super.onResume();        Log.i(TAG, "onResume");    }    @Override    protected void onPause() {        Log.i(TAG, "onPause");        super.onPause();    }    @Override    protected void onDestroy() {        Log.i(TAG, "onDestroy");        super.onDestroy();    }}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.devnn.demo">    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/Theme.Devnn">        <activity            android:name="com.devnn.demo.ActivityA"            android:launchMode="singleInstance"></activity>        <activity            android:name="com.devnn.demo.MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>