第一行代码 Activity探究笔记
  HvTJUzsxOBtS 2023年11月25日 49 0


####1、怎样将一个activity 设为一个主活动
需要在activity 里面添加标签

省``````略
        <activity
            android:name=".FirstActivity"
            android:label="This is FirstActivity"
            android:launchMode="singleTask">
            //添加以下两句即可
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>

省``````略

如果一个程序中没有声明任何主活动,这个程序仍然可以安装,但是无法在启动器中看到,或者打开这个程序。这种程序一般都是作为第三方服务供其他程序内部调用如:支付宝快捷支付。

####2、使用显式Intent 和隐式Intent 实现 activity 跳转
#####2.1)显式Intent

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                startActivity(intent);

#####2.2)隐式Intent
(1)通过在配置的内容,指定当前活动能够响应的action和category
在AndroidManifest.xml文件,添加代码

<activity
            android:name=".SecondActivity"
            android:launchMode="singleInstance">
            <intent-filter>
            //一个activity 只能响应一个action,但是可以响应多个category
                <action android:name="com.example.activitytest.ACTION_START" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="com.example.activitytest.MY_CATEGORY" />
            </intent-filter>
</activity>

(2) 这样我们通过

Intent intent = new Intent("com.example.activitytest.ACTION_START");
                startActivity(intent);

或者

Intent intent = new Intent("com.example.activitytest.ACTION_START");
//通过 addCategory()方法 添加一个 Category    
         intent.addCategory("com.example.activitytest.MY_CATEGORY")
                startActivity(intent);

都可以打开secondActivity.
添加的 Category ,在打开的 Intent中的标签里要含有,不然会报错。

(3)更多的带有参数的 intent

Intent intent = new Intent(Intent.ACTION_DIAL);
                intent.setData(Uri.parse("tel:10086"));
                startActivity(intent);

将会调用dialer 拨打 10086

####3、向下一个activity传递数据

(1)first activity

String data = "hello second";
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("extra_data",data);
startActivity(intent);

这里通过调用putExtra()方法来传递一个数据,第一个参数是键值,第二个是数据

(2)second Activity
我们在第二个 activity 中获取数据

Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity",data);

第二个acticity 通过调用getIntent()方法 获取 启动本身的Intent, 然后通过调用getStringExtra()方法,获取传递的数据。
获取传递的数据根据类型不一样,可以使用getIntExtra(),getBooleanExtra()等。

####4、返回数据给上一个Activity
两个activity: FirstActivity SecondActivity
1)首先FirstActivity跳转到SecondActivity

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent,1);

这里的startActivityForResult()方法用来启动SecondActivity,1使用一个请求码,一个数值就好。

2)在SecondAcyivity 活动中添加返回的逻辑代码

Intent intent = new Intent();
intent.putExtra("data_return","hello FirstActivity");
setResult(RESULT_OK,intent);
finish();

我们可以看到也是构建了一个intent ,但是这个intent并没有任何跳转意图,知识单纯的传递数据。
setResult() 这个方法是专门向上一个活动返回数据的。setResult()方法接收两个参数:
(1)第一个参数用于向上一个活动返回处理结果,一般为 RESULT_OK 和  RESULT_CANCELED。
(2)第二个参数把带有数据的Intent传递回去,然后调用finish()销毁当前activity.

由于我们是使用startActivityForResult()方法来启动SecondActivity的,在SecondActivity被 finish() 毁掉之前,会回调上一个活动onActivityResult()方法。因此我们需要在FirstActiviy活动中重写这个方法,来得到返回的数据。

3)在FirstActivity中复写onActivityResult()方法

@Override
protected void onActivityResult(int requestcode, int resultCode , Intent data) {
switch (requestcode) {
	case 1:
		if (resultcode == RESULT_OK) {
		String returnedDta = data.getStringExtra("data_return");
		Log.d("FirstActivity",returnedData);
		}
		break;
	default:
		break;
	}
}

onActivityResult() 函数有三个参数,requestcode 就是我们上面传入的请求码。 resultCode 来判断处理的结果是否成功  。 data 就是传入的数据。

4)在此我们有个提示:onActivityResult() 是在通过finish() 销毁后,被回调的。
倘若activity 是通过Black按键 返回 ,有什么方法也是同样回调呢?
这就需要我们重写一个 onBackPressed() 方法来解决。

@Override
public void onBackPress(){
	Intent intent = new  Intent();
	intent.putExtra("data_return","hello FirstActivity");
	setResult(RESULT_OK,intent);
	finish();
}

这样的话,当按下Back 按键 ,就会执行onBackPressed()方法。

####5、活动的生命周期
#####1)每一个活动在生命周期都有四种状态
(1)运行状态
这时活动处于栈顶,我们能够看见。
(2)暂停状态
活动不处于栈顶,但依然可见。比如有提示框,下面的activity
(3)停止状态
活动不在栈顶位置,同时不可见。比如一个界面跳到了另一个界面
(4)销毁状态
从栈中移除。

#####2)活动的生存周期
Activity 定义了7种回调方法,来覆盖活动的每一个生命周期。
(1)onCreate()
会在活动生命周期第一次被创建的时候被调用。
(2)onStart()
这个方法由不可见到可见的时候被调用。
(3)onResume()
这个是活动准备好与用户交互的时候使用,活动处于运行状态。
(4)onPause() 
这个是系统准备启动另一个活动或恢复另一个活动时启动。(启动的活动是对话框也会被调用)
(5)onStop()
这个会在活动完全不可见的时候调用。(启动的活动是对话框 不会被调用)
(6)onDestory()
会在活动被销毁之前调用,之后活动状态就是销毁状态
(7)onRestart()
这个方法由停止状态边长运行状态调用,没结束前 在onStop() 函数后运用。

这7个方法除了onRestart() 其余都是两两对应一个生存期
(1)完整生存期 onCreat()  & onDestory()
(2)可见生存期 onStart() & onStop()
(3)前台生存期 onResume() & onPause()

####6、更改一个Activity 为Dialog 属性

<activity android:name=".DialogActivity">
	android:theme="@style/Theme.AppCompat.Dialog">
</activity>

这是让当前的DialogActivity使用 对话框式的主题。

####7、活动 由于内存原因被回收
1)比如从A 活动 跳到 B 活动,此时A 活动进入 停止状态,然后由于内存占用较大原因。A活动被回收了,也就是销毁了。
2)虽然此时按Back键,仍然能够回到A 活动,但是此时A 活动并不是通过onRestart()唤醒。而是重新onCreat()创建。
3)此时由于A活动是新创建的,会丢失一些数据。

接下来我们就讨论怎么恢复这些数据。
(1)Activity 中 提供了 onSaveInstanceState()回调方法,这个方法会在活动被回收之前调用。
(2)onSaveInstanceState()方法会携带一个Bundle类型的参数,bundle提供一系列的方法用于保存数据。

@Override
protected void onSaveInstanceState(Bundle outState) {
	super.onSaveInstanceState(outState);
	String temDate = "Something just typed";
	outState.putString("data_key", temDate);
}

这样需要保存的数据就已经保存了。

那么怎么样数据恢复呢,我们发现onCreat()方法里面也有一个Bundle类型的参数,这个参数一般都是null,但是回收之前通过onSaveInstanceState()方法保存数据的话,我们可以通过它来恢复数据。
修改 onCreat()的方法

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreat(savedInstanceState);
	Log.d(TAG,"on Create```");
	setContentView(R.loyout.activity_main);
	if (savedInstanceState != null) {
		String temData = savedInstanceState.getString("data_key");
		Log.d(TAG, temData);
	}
}

然后把取出来的值放到相应的位置就好。

####8、活动的启动模式
活动总共有四种启动模式
standard 、 singleTop 、 singleTask 、 singleInstance

可以在AndroidManifest.xml 中通过标签来选择启动属性。

#####1)standard
这种是默认的启动。
比如一个栈中 ,
活动A -> 活动A -> 活动A 可以这样的 启动
活动A -> 活动B ->活动A -> 活动A
就是一个页面启动之后,还可以在启动一次。

#####2)single Top

<activity android:name=".DialogActivity">
	android:launchMode = "singleTop"
</activity>

一个栈 中:
活动A -> (此时要是再打开活动A,不再会创建)
活动A -> 活动B -> 活动A -> 活动A ->
就是它会检查一个栈(栈顶) 里面 有没有已经打开的活动,有的话,就不会重新创建。

#####3)single Task

<activity android:name=".DialogActivity">
	android:launchMode = "singleTask"
</activity>

一个栈 中:
活动A -> (此时要是再打开活动A,不再会创建)
活动A -> 活动B -> 活动A (此时会检查栈前面有没有已经打开的活动,如果有 就不再创建,而是平移过来。)

比singleTop 多了,不是栈顶部 也不需要创建。

#####4)singleInstance
不同与以上三种,指定singleInstance 模式的活动会启动一个新的栈来管理这个活动。这样不管哪个应用程序来访问这个活动,都共用同一个返回栈 ,也就解决了共享活动实例的问题。

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

这样 活动A -> 活动B -> 活动C ->

按Back键 会退到活动A , 再按一次 会退到活动B

通过Log.d(TAG,“Task id is” + getTaskId());
可以查看到不同的B 和A/C是不同的栈 之中。

文献参考:
第一行代码 Android 第二版 郭霖

本人郑重声明,本博客所著文章、图片版权归权利人持有,本博只做学习交流分享所用,不做任何商业用途。访问者可將本博提供的內容或服务用于个人学习、研究或欣赏,不得用于商业使用。同時,访问者应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人的合法权利;如果用于商业用途,须征得相关权利人的书面授权。若以上文章、图片的原作者不愿意在此展示內容,请及时通知在下,將及时予以刪除。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月25日 0

暂无评论

HvTJUzsxOBtS