《你的第一行Android代码》菜鸡的自学日记-第六天

本文深入探讨了Android中活动(Activity)的四种启动模式:standard、singleTop、singleTask和singleInstance,解析了它们的工作原理及应用场景。同时,介绍了如何通过日志确定当前界面对应的活动,以及实现程序即时退出的技巧。

一.活动的启动模式

在AndroidManifest.xml中< activity >标签中指定android:launchMode属性来选择启动模式

  • standard
  • singleTop
  • singleTask
  • singleInstance

(加了*号的就是修改的代码)

1.standard(默认模式)

在standard模式下,每启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置,它并不会检查返回栈中是否已经存在这个活动,每次启动都会创建一个新的示例
在这里插入图片描述

打开ActivitryTest项目,修改FirstActivity中onCreate()方法的代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      * Log.d("FirstActivity",this.toString());
        
        // setContentView()方法中传入布局文件的ID
        setContentView(R.layout.first_layout);

        //通过findViewById()来获得布局文件中定义的元素
        Button button1 = (Button) findViewById(R.id.button_1);

        //调用setOnClickListener()方法为button 1注册一个监听器
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              *  Intent intent = new Intent(FirstActivity.this,FirstActivity.class);
                 startActivity(intent);
            }
        });

连续点击两下Button 1,再使用关键字过滤功能“D/FirstActivity: ”,会打印日志中会看见三条类似的打印信息。这说明每点击一次按钮就会创建一个新的FirstActivity实例,返回栈中也会存在3个FirstActivity实例,需要连按三次Back键才能退出程序。

2.singleTop

当启动活动时发现返回栈栈顶已经是该活动,则会直接使用它。
在这里插入图片描述

打开AndroidManifest.xml,修改FirstActivity的启动模式:

 <activity
            android:name=".FirstActivity"
          * android:launchMode="singleTop"
            android:label="This is FirstActivity">

重新运行程序时,logcat中已经创建了一个FirstActivity实例,之后不管按多少次按钮,都不会出现新的打印信息,因为它会一直调用栈顶的FirstActivity实例,因此返回栈中也只会存在一个FirstActivity实例.

但是如果FirstActivity没有处于栈顶,,再次启动FirstActivity,还是会创建一个新的FirstActivity实例。

3.singleTask

每次启动活动时首先在返回栈中检查是否已经存在该活动,存在直接使用该活动,不存在就创建一个新的实例
在这里插入图片描述
打开AndroidManifest.xml,修改FirstActivity的启动模式:

<activity
            android:name=".FirstActivity"
         *  android:launchMode="singleTask"
            android:label="This is FirstActivity">
            <intent-filter>

在FirstActivity添加onRestart()方法,并打印日志:

 protected void onRestart(){
        super.onRestart();
        Log.d("FirstActivity","onRestart");
    }

在SecondActivity添加onDestroy()方法,并打印日志:

protected void onDestroy(){
        super.onDestroy();
        Log.d("SecondActivity","onDestroy");
    }

重新运行程序,从FirstActivity点击按钮到SecondActivity,再从SecondActivity点击按钮回到FirstActivity。从打印信息可以看出,至始至终我们只有一个FirstActivity实例,一个SecondActivity实例。

4.singleInstance

指定singleInstance模式的活动会启用一个新的返回栈来管理这个活动,用于解决共享活动的问题

在这里插入图片描述
打开AndroidManifest.xml,修改SecondActivity的启动模式:

<activity android:name=".SecondActivity"
            android:launchMode="singleInstance">

修改FirstActivity中onCreate()方法中的代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      * Log.d("FirstActivity","Task id is"+getTaskId());
        // setContentView()方法中传入布局文件的ID
        setContentView(R.layout.first_layout);

        //通过findViewById()来获得布局文件中定义的元素
        Button button1 = (Button) findViewById(R.id.button_1);

        //调用setOnClickListener()方法为button 1注册一个监听器
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });

修改SecondActivity中onCreate()方法中的代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    *   Log.d("SecondActivity","Task id is"+getTaskId());
        setContentView(R.layout.second_layout);
        Button button2 = (Button)findViewById(R.id.button_2);

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
             *  Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);
                startActivity(intent);
            }
        });

修改ThirdActivity中onCreate()方法中的代码:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     *  Log.d("ThirdActivity","Task is is"+getTaskId());
        setContentView(R.layout.third_layout);
    }

运行程序,从FirstActivity点击按钮进入SecondActivity,再从SecondActivity点击按钮ThirdActivity,可以看见logcat中的打印信息:
在这里插入图片描述
FirstActivity和ThirdActivity处于相同的返回栈,而SecondActivity处于另外一个单独的返回栈。

因为FirstActivity和ThirdActivity处于相同的返回栈所以点击Back键会直接从ThirdActivity回到FirstActivity,再从点击Back键则会显示SecondActivity。

二.活动的实践技巧

1.我在哪个活动?

com.example.activitytest/New/Java Class,输入name:BaseActivity,kind:Class。

让BaseActivity继承自AppCompatActivity,重写onCreate()方法:

public class ThirdActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("ThirdActivity","Task is is"+getTaskId());
        setContentView(R.layout.third_layout);
    }
}

让BaseActivity成为FirstActivity,SecondActivity,ThirdActivity的父类。运行程序,点击按钮由FirstActivity进入SecondActivity进入ThirdActivity,在logcat可以看见:
在这里插入图片描述
哪个活动的类名被打印出来,就说名这个界面对应的哪个活动

2.随时随地退出程序

新建一个ActivityCollector类作为活动管理器:

public class ActivityCollector {
    public static List<Activity> activities = new ArrayList<>();

    public static void addActivtiy(Activity activity){
        activities.add(activity);
    }

    public static void removeActivity(Activity activity){
        activities.remove(activity);
    }

    public static void finishAll(){
        for (Activity activity : activities){
            if (!activity.isFinishing()){
                activity.finish();
            }
        }
        activities.clear();
    }
}

在ActivityCollector中,通过List暂存活动addActivtiy向List添加一个活动removeActivity向List删除一个活动finishAll用于销毁List中所有的活动

修改BaseActivity中的代码:

public class BaseActivity extends AppCompatActivity{

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity",getClass().getSimpleName());
        ActivityCollector.addActivtiy(this);
    }

    protected void onDestroy(){
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

调用 ActivityCollector.finishAll()就可以在任意地方退出程序,例如在ThirdActivtiy界面点击按钮退出程序:

public class ThirdActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("ThirdActivity","Task is is"+getTaskId());
        setContentView(R.layout.third_layout);
        Button button3 = (Button)findViewById(R.id.button_3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ActivityCollector.finishAll();
            }
        });
    }
}

小结:了解了四种活动的启动模式;学会如何知道当前界面对应哪个活动;知道了怎么随时随地退出活动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值