安卓之Activity数据交换及生命周期

550 阅读4分钟

Activity数据交换

MainAcvity -> SubActivity
  • 隐式Intent 是指在创建 Intent 对象时,不指定具体的接收者,而是定义要执行的 Action、Category 和 Data,然后让 Android 系统根据相应的匹配机制找到要启动的 Activity。 MainActivity:
btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Intent intent = new Intent(MainActivity.this,SubActivity.class);
                Intent intent = new Intent();
                intent.setAction("com.dengyu.ui.SubActivity");
                Bundle b = new Bundle();
                b.putString("name","mask");
                b.putInt("age",23);
                intent.putExtras(b);
                startActivity(intent);
            }
        });

AndroidManifest.xml:

<activity android:name=".SubActivity">
    <intent-filter>
        <action android:name="com.dengyu.ui.SubActivity" />
            
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

SubActivity:

tv = findViewById(R.id.tv);
Intent intent = getIntent();
Bundle extras = intent.getExtras();

String name = extras.getString("name");
int age =  extras.getInt("age");
ShowUtil.d("SubActivity",name + "," + age);
tv.setText(name + "," + age);
  • 显式Intent 是指在创建 Intent 对象时,就指定接收者(如 Activity、Service 或者 BroadcastReceiver),因为我们已经知道要启动的 Activity 或者 Service 的类名称。 MainAcvtivity:
btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,SubActivity.class);
                //Intent intent = new Intent();
                //intent.setAction("com.dengyu.ui.SubActivity");
                Bundle b = new Bundle();
                b.putString("name","mask");
                b.putInt("age",23);
                intent.putExtras(b);
                startActivity(intent);
            }
        });

AndroidManifest.xml:

<activity android:name=".SubActivity" />
MainAcvity -> SubActivity -> MainActivity

在一个 Activity 中调用另一个 Activity,当用户在第二个 Activity 中选择完成后,程序将自动返回到第一个 Activity 中,第一个 Activity 能够获取并显示用户在第二个 Activity 中选择的结果。

通过 Intent 和 Bundle 来实现。与在两个 Activity 之间交换数据不同的是,此处需要 使用startActivityForResult()方法来启动另一个Activity。调用startActivityForResult()方法启动Activity后, 关闭新启动的 Activity 时,可以将选择的结果返回到原 Activity 中。

/**
* 将以指定的请求码启动 Activity,并且程序将会获取新启动的 Activity 返回的结果通过重写 onActivityResult()方法来获取
* @param intent
* @param requestCode 启动 Activity 的请求码, 用于标识
*/
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode)

MianActivity:

public class MainActivity extends AppCompatActivity {
    public Button btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,SubActivity.class);

                Bundle b = new Bundle();
                b.putString("name","dnegyu");
                b.putInt("age",23);
                intent.putExtras(b);
//                startActivity(intent);
                startActivityForResult(intent,0x01);
            }


        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0x01 && resultCode == Activity.RESULT_OK)
            Toast.makeText(MainActivity.this, data.getExtras().getString("key"), Toast.LENGTH_LONG).show();
    }
}

SubActivity:

public class SubActivity extends AppCompatActivity {
    public TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);
        tv = findViewById(R.id.tv);
        final Intent intent = getIntent();
        Bundle extras = intent.getExtras();

        String name = extras.getString("name");
        int age =  extras.getInt("age");
        ShowUtil.d("SubActivity",name + "," + age);
        tv.setText(name + "," + age);

        findViewById(R.id.sub_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent1 = new Intent(SubActivity.this,MainActivity.class);
                Bundle bb = new Bundle();
                bb.putString("key","i am back");
                intent.putExtras(bb);
                setResult(Activity.RESULT_OK,intent);
                finish();
            }
        });
    }
}

Activity生命周期

有了前面的案列,我们可以很清楚的测试Activity的声明周期。

MainActivity:

public class MainActivity extends AppCompatActivity {
    public Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ShowUtil.d("xixi","MainActivity --> onCreate");
        setContentView(R.layout.activity_main);
        btn = findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,SubActivity.class);

                Bundle b = new Bundle();
                b.putString("name","mask");
                b.putInt("age",23);
                intent.putExtras(b);
                startActivityForResult(intent,0x01);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        ShowUtil.d("xixi","MainActivity --> onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        ShowUtil.d("xixi","MainActivity --> onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        ShowUtil.d("xixi","MainActivity --> onPause");

    }

    @Override
    protected void onStop() {
        super.onStop();
        ShowUtil.d("xixi","MainActivity --> onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ShowUtil.d("xixi","MainActivity --> onDestroy");
    }
    
    @Override
    protected void onRestart() {
        super.onRestart();
        ShowUtil.d("xixi","MainActivity --> onRestart");
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0x01 && resultCode == Activity.RESULT_OK)
            Toast.makeText(MainActivity.this, data.getExtras().getString("key"), Toast.LENGTH_LONG).show();
    }
}

SubActivity:

public class SubActivity extends AppCompatActivity {
    public TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ShowUtil.d("xixi","SubActivity --> onCreate");

        setContentView(R.layout.activity_sub);
        tv = findViewById(R.id.tv);
        final Intent intent = getIntent();
        Bundle extras = intent.getExtras();

        String name = extras.getString("name");
        int age =  extras.getInt("age");
        ShowUtil.d("SubActivity",name + "," + age);
        tv.setText(name + "," + age);

        findViewById(R.id.sub_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent1 = new Intent(SubActivity.this,MainActivity.class);
                Bundle bb = new Bundle();
                bb.putString("key","i am back");
                intent.putExtras(bb);
                setResult(Activity.RESULT_OK,intent);
                finish();
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        ShowUtil.d("xixi","SubActivity --> onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        ShowUtil.d("xixi","SubActivity --> onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        ShowUtil.d("xixi","SubActivity --> onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        ShowUtil.d("xixi","SubActivity --> onStop");
    }
    
    @Override
    protected void onRestart() {
        super.onRestart();
        ShowUtil.d("xixi","SubActivity --> onRestart");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ShowUtil.d("xixi","SubActivity --> onDestroy");
    }
}

从MainActivity到SubActivity,接着返回到MainActivity。观测日志的情况。

  1. 加载MainActivity时,日志如下:
D/xixi: MainActivity --> onCreate
D/xixi: MainActivity --> onStart
D/xixi: MainActivity --> onResume
  1. 点击跳转SubActivity按钮,日志如下:
D/xixi: MainActivity --> onPause
D/xixi: SubActivity --> onCreate
D/xixi: SubActivity --> onStart
D/xixi: SubActivity --> onResume
D/xixi: MainActivity --> onStop
  1. 在SubActivity中点返回按钮回到MainActivity,日志如下:
D/xixi: SubActivity --> onPause
D/xixi: MainActivity --> onRestart
D/xixi: MainActivity --> onStart
D/xixi: MainActivity --> onResume
D/xixi: SubActivity --> onStop
D/xixi: SubActivity --> onDestroy

通过观测,发现确实与官方提供的Activity生命周期时相符的。如下:

activity_lifecycle.png

在1.步中,MainActivity被create\start\resume,然后进行运行状态;

在2.步中,MainActivity跳转到SubActivity,首先进入暂停状态,这时候activity还是可见的,之后SubActivity被create\start\resume被进入栈顶,MainActivity进去stop状态,已经不可见了。

在3.步中,我们通过按钮返回到MainActivity,重新激活了MainActivity获得了焦点。而SubActivity执行finish,直接被销毁。

Activity的四个状态

  • 运行状态 当前的 Activity,位于 Activity 栈顶,用户可见,并且可以获得焦点
  • 暂停状态 失去焦点的 Activity,仍然可见,但是在内存低的情况下,不能被系统 killed(杀死)
  • 停止状态 该 Activity 被其他 Activity 所覆盖,不可见,但是它仍然保存所有的状态和信息。当内存低的情况下,它将会被系统 killed(杀死)
  • 销毁状态 该 Activity 结束,或 Activity 所在的虚拟器进程结束

四个状态的详细说明以及回调方法说明,可参考官网: developer.android.google.cn/guide/compo…