Android四大组件中的Activity

目录

      • 一、关于Activity
      • 二、Intent和IntentFilter
      • 三、显示Activity和隐式Activity
      • 四、Activity传值
        • 方法一:intent
        • 方法二、Bundle
      • 五、得到Activity返回的数据
        • 步骤一:
        • 步骤二:
        • 步骤三:
      • 六、知道当前处在哪个Activity
      • 七、随时随地退出程序
      • 八、启动Activity的最佳写法

一、关于Activity

Android四大组件中的Activity_第1张图片

二、Intent和IntentFilter

Android四大组件中的Activity_第2张图片

三、显示Activity和隐式Activity

Android四大组件中的Activity_第3张图片

Android四大组件中的Activity_第4张图片

四、Activity传值

方法一:intent

Android四大组件中的Activity_第5张图片

方法二、Bundle

Android四大组件中的Activity_第6张图片

Android四大组件中的Activity_第7张图片
Intent和Bundle传值上的区别?
假设数据需要从A页面传到B页面再传到C页面
Intent
A页面

    Intent intent=new Intent(MainActivity.this,BActivity.class);
    intent.putExtra("String","MainActivity中的值");
    intent.putExtra("int",11);
    startActivity(intent);

B页面

 Intent intent = getIntent();
   String string = intent.getStringExtra("String");
   Int key = intent.getIntExtra("int",0);
   Intent intent=new Intent(BActivity.this,CActivity.class);
    intent.putExtra("String1",string);
    intent.putExtra("int1",key);
    intent.putExtra("boolean",true);
    startActivity(intent);

C页面

Intent intent4=getIntent();//获取上一个页面的意图
String data4=intent4.getStringExtra("String");//通过名字获取上一个页面传递的数据
Int key4 = intent.getIntExtra("int",0);
Boolean bool=intent.getBooleanExtra("boolean",true);

可以看到,使用的时候不方便的地方是需要在B页面将数据一条条取出来然后再一条条传输给C页面。而使用Bundle的话,在B页面可以直接取出传输的Bundle对象然后传输给C页面。

Bundle

A页面中

 Intent intent = new Intent(MainActivity.this, BActivity.class);
    Bundle bundle = new Bundle();
    bundle.putString("String","MainActivity中的值");
    bundle.putInt("int",11);
    intent.putExtra("bundle",bundle);
    startActivity(intent);

B页面中

//接受数据
Intent intent = getIntent();
Bundle bundle=intent.getBundleExtra("bundle");
//发送数据
    Intent intent=new Intent(BActivity.this,CActivity.class);
    //可以传给CActivity额外的值
    bundle.putBoolean("boolean",true);
    intent.putExtra("bundle1",bundle);
    startActivity(intent);

Bundle 可通过上一个页面getIntent().getBundleExtra(“上个页面的key”),来取到上个页面的数据,当前页面需要其他数据时,只需在当前页面继续加即可。而Intent想要获取数据的话,每次都要 Intent intent = getIntent(); String string = intent.getStringExtra(“String”);Int key = intent.getIntExtra(“int”,0);这样会比较麻烦

Bundle可对对象进行操作,而Intent是不可以。Bundle相对于Intent拥有更多的接口,用起来比较灵活,但是使用Bundle也还是需要借助Intent才可以完成数据传递总之,Bundle旨在存储数据,而Intent旨在传值。

五、得到Activity返回的数据

Android四大组件中的Activity_第8张图片

步骤一:

Android四大组件中的Activity_第9张图片

步骤二:

Android四大组件中的Activity_第10张图片
第二张图,有细节写错,是通过setResult()方法传递数据给MainActivity

步骤三:

Android四大组件中的Activity_第11张图片
代码部分
MainActivity

package com.example.getbackdata;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    public final static int REQUST_CODE=1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void firstbutton(View view) {
        //步骤一:
        Intent intent=new Intent(this,otherActivity.class);
        startActivityForResult(intent,REQUST_CODE);
    }

    //因为我们是使用startActivity来启动otherActivity的,所以当otherActivity被finish()销毁
    // 后,他会自动回调MainActivity中的onActivityResult方法。而otherActivity也通过setResult()方
    //法将数据传递到了MainActivity,此时我们在MainActivity中设置onActivityResult方法来接收
    //返回的数据
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable  Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode)
        {
            case REQUST_CODE:
                if(resultCode==0) {
                    TextView mainText = (TextView) findViewById(R.id.mainText);
                    mainText.setText(data.getStringExtra("result"));
                }
                 //data携带返回数据的intent
                 break;
            default:
        }
    }
}

因为我们是使用startActivity来启动otherActivity的,所以当otherActivity被finish()销毁 后,他会自动回调MainActivity(上一个活动)中的onActivityResult方法。而otherActivity也通过setResult()方法将数据传递到了MainActivity,此时我们在MainActivity中设置onActivityResult方法来接收

otherActivity

package com.example.getbackdata;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class otherActivity extends AppCompatActivity {

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

    public void button2(View view) {
        //步骤二
        EditText otheredit = (EditText) findViewById(R.id.otheredit);
        Intent intent=new Intent();//
        intent.putExtra("result",otheredit.getText().toString());
        this.setResult(0,intent);
        //通过setResult传递数据给MainActivity
        //setResult两个参数(第一个是:请求码,第二个是将带有数据的intent传递到MainActivity)
        finish();
    }
}

Android四大组件中的Activity_第12张图片
Android四大组件中的Activity_第13张图片
Android四大组件中的Activity_第14张图片
请求码是用来区分打开activity的是哪一个按钮,结果码是用来区分当前传回的数据来自于哪一个activity。
父Activity也就是 startActivityForResult所在的Activity,子Activity是 setResult所在的Activity
从子Activity获取返回结果
public void startActivityForResult(Intent intent, int requestCode)
该方法的第一个参数是intent,第二个参数是请求代码。请求代码先发送给子activity,然后再返回给父activity的用户定义整数值。当一个activity启动多个不同类型的子activity,且需要判断区分消息回馈方时,通常会用到该请求代码

设置返回结果
public final void setResult(int resultCode)
public final void setResult(int resultCode,Intent data)
一般来说,参数resultCode可以是以下两个预定义常量中的任何一个
Activity.RESULT_OK
Activity.RESULT_CANCELED

六、知道当前处在哪个Activity

新建一个BaseActivity继承自AppCompatActivity,并重写onCreate()方法

open class BaseActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("BaseActivity", javaClass.simpleName)
    }
}

我们在onCreate()方法中加了一行日志,用于打印当前实例的类名。Kotlin中的BaseActivity::class.java表示获取BaseActivity类的class对象,相当于在Java中调用BaseActivity.class。在上述代码中,我们先获取了当前实例的Class对象,然后再调用simpleName获取当前实例的类名。
接下来我们同样让Activity继承BaseActivity。为了使得BaseActivity可以被继承已经在类名的前面加上open关键字。
这样每当我们进入一个Activity界面,该Activity的类名就会被打印出来,这样我们就能知晓当前界面对应哪一个Activity了。

七、随时随地退出程序

如果你的手机界面还停留在ThirdActivity,你会发现当前退出程序是非常不方便的,需要连按3次Back键才行。如果我们的程序需要注销或者退出的功能怎么办呢?就需要一个能随时随地都能退出程序的方案才行。
解决方法就是用一个专门的集合来对所有的Activity进行管理就可以了。

object ActivityCollector {
    private val activities=ArrayList<Activity>()

    fun addActivity(activity: Activity){
        activities.add(activity)
    }

    fun removeActivity(activity: Activity){
        activities.remove(activity)
    }

    fun finishAll(){
        for(activity in activities){
            if(!activity.isFinishing){
                activity.finish()
            }
        }
        activities.clear()
    }
}

这里使用单例类,是因为全局只需要一个Activity集合。在集合中,我们通过一个ArrayList来暂存Activity,,然后提供了一个addActivity()方法,用于向ArrayList中添加Activity;提供了一个removeActivity()方法,用于从ArrayList中移除Activity;最后提供一个finishAll()方法,用于将ArrayList中存储的Activity全部销毁。注意在销毁之前我们还需要先调用activity.isFinishing来判断Activity是否正在销毁中,因为Activity还可能通过按下Back键等方式被销毁,如果该Activity没有正在销毁中,我们再去调用他的finish()方法来销毁他。

open class BaseActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("BaseActivity", javaClass.simpleName)
        ActivityCollector.addActivity(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        ActivityCollector.removeActivity(this)
    }
}

在BaseActivity的onCreate()方法调用了ActivityCollector的addActivity()方法,表明将当前正在创建的Activity添加到集合里。然后在BaseActivity中重写onDestroy()方法,并调用ActivityCollector的removeActivity()方法,表明从集合里移除一个马上要销毁的Activity。
所以当你想要在什么地方退出程序,只需要调用ActivityCollector.finishAll()方法就可以了。

八、启动Activity的最佳写法

假设有一个SecondActivity中需要用到两个非常重要的字符串参数,在启动SecondActivity的时候必须传递过来,我们很容易写出如下代码

var intent=Intent(this,SecondActivity::class.java)
intent.putExtra("param1","data1")
intent.putExtra("param2","data2")
startActivity(intent)

虽然这样写是正确的,但是当我们不清楚启动SecondActivity需要传递哪些数据的时候,会很麻烦,这个时候我们可以换一种写法。

    companion object{
        fun actionStart(context: Context, data1:String, data2:String){
            val intent=Intent(context,SecondActivity::class.java)
            intent.putExtra("param1",data1)
            intent.putExtra("param2",data2)
            context.startActivity(intent)
        }
    }

我们使用 companion object的语法结构,并在compainion object中定义一个actionStart()方法,之所以这么写,是因为Kotlin规定,所有定义在compainion object中的方法都可以使用类似于Java静态方法的形式调用。在actionStart()方法中完成了对Intent的构建,另外所有SecondActivity中需要的数据都通过actionStart()方法的参数传递过来的,然后把它们存储到Intent中,最好调用startActivity()方法启动SecondActivity。
这样写的好处就是一目了然,SecondActivity中需要的数据在方法中全部体现出来了,另外还简化了启动Activity的代码,只需要一行即可

     button.setOnClickListener {
            SecondActivity.actionStart(this,"data1","data2")
        }

你可能感兴趣的:(Android,android,android,studio)