Android四大组件之Activity


再写四大组件之前,先说一些权限的事情,比如打电话,需要打电话的权限,上网,需要访问网络权限,本地保存文件,需要SD卡读写权限等等,而且在Android6.0之后谷歌把权限分成两类了,一类是普通权限,一类是危险权限,普通权限在清单文件配置一下就行了,危险权限需要动态申请,权限太多了,我就没总结,我看到有人总结了,我把地址分享出来 Android6.0权限大全和权限分类.记住 一定要设置或者申请权限

Android有四大组件

Activity,Service,BroadcastReceiver,ContentProvider。对应的中文分别是-活动,服务,广播接收者,内容提供者。
Activity在你创建项目的时候就会自动创建一个MainActivity,Activity绑定这layout布局文件,用来显示页面,和用户交互。

Activity生命周期

大白话版说一下Activity生命周期,先把声明周期图贴出来:
Activity生命周期图

onCreate

这个方法,代表创建,既然是创建,那么一般都是创建一次,所以这里的onCreate就是创建一次,而且在这个方法里面需要设置Activity显示的layout布局文件。

onStart

这个方法是在当页面可见的时候,就回执行这个方法了。反正我是这么理解的。

onRestart

这个是当页面重新可见的时候,才会执行的方法。

onResume

这个是当页面可操作的时候,才会执行,就是说有个button,当执行这个方法了,这个button就可以点击了,而onStart方法执行的时候,这个button还是不能点击的,只是你能看大这个按钮。

onPause

这个方法是和onResume对应的,这个方法执行的时候,是页面不能操作的时候,就是说你还能看到控件,按钮,但是都不能点击了。

onStop

这个方法是和onStart对应的,当这个方法执行的时候,就是页面看不见的时候。

onDestroy

这个方法是和onCreate方法对应的,这个方法就是当页面销毁的时候回执行的,通常在这里处理一些不需要的引用,防止内存泄漏。销毁有两种,一种是长时间不用,系统回收了,另一种是手动调用finish方法,比如你跳转到下一个页面的时候,本页面没用了,就顺便调一下finish方法,就在android的任务栈中清除了。

面试会问的一个关于生命周期的问题

A开启B,各自生命周期如何执行

这里有两个activity,一个A,一个B,你当前操作的是A,问当A跳转到B时,两个Activity会如何执行各自的声明周期。
答案:A onPause-> B onCreat->B onStart -> B onResume ->A onStop
为什么会这样呢,仔细想想就明白了,在B还没有创建出来的时候,如果A就不可见了,那么这个应用应该显示哪个页面呢?总不能空着或者黑屏把,所以首先让A不可交互,防止误操作,然后当B页面完全加载出来之后,B就是可见可操作了,A自然就是不可见了。也就是说,如果你卡了一个透明的B,那么A就只会执行onPause,不会执行onStop。因为A是一直可见的。

2020-03-19 14:29:35.100 17469-17469/com.example.mylearn D/Lifecycle: MainActivity->onCreate
2020-03-19 14:29:35.103 17469-17469/com.example.mylearn D/Lifecycle: MainActivity->onStart
2020-03-19 14:29:35.105 17469-17469/com.example.mylearn D/Lifecycle: MainActivity->onResume
//上面是启动MainActivity执行的生命周期
//下面是MainActivity打开Main2Activity页面两个Activity各自的生命周期打印的顺序
2020-03-19 14:29:40.183 17469-17469/com.example.mylearn D/Lifecycle: MainActivity->onPause
2020-03-19 14:29:40.216 17469-17469/com.example.mylearn D/Lifecycle: Main2Activity->onCreate
2020-03-19 14:29:40.219 17469-17469/com.example.mylearn D/Lifecycle: Main2Activity->onStart
2020-03-19 14:29:40.220 17469-17469/com.example.mylearn D/Lifecycle: Main2Activity->onResume
2020-03-19 14:29:40.699 17469-17469/com.example.mylearn D/Lifecycle: MainActivity->onStop
横竖屏切换生命周期

还有一个与生命周期有关的,就是横竖屏切换的时候声明周期如何执行呢?
答案:onpause->onStop->onDestroy->onCreate->onStart->onResume。会先销毁,重新创建一遍Activity。看下面日志

2020-03-19 17:04:38.374 8478-8478/com.example.mylearn D/Lifecycle: MainActivity->onPause
2020-03-19 17:04:38.375 8478-8478/com.example.mylearn D/Lifecycle: MainActivity->onStop
2020-03-19 17:04:38.375 8478-8478/com.example.mylearn D/Lifecycle: MainActivity->onDestroy
2020-03-19 17:04:38.436 8478-8478/com.example.mylearn D/Lifecycle: MainActivity->onCreate
2020-03-19 17:04:38.439 8478-8478/com.example.mylearn D/Lifecycle: MainActivity->onStart
2020-03-19 17:04:38.441 8478-8478/com.example.mylearn D/Lifecycle: MainActivity->onResume

如果你想设置你这个应用固定横屏或者固定竖屏,那么,在清单文件中这是一个属性就可以了。
固定竖屏
固定横屏

生命周期我觉得就这些了。

Activity启动模式

下面说一下Activity的启动模式,在说启动模式之前,先提一下栈这个概念。
jvm中有堆和栈,那么在Android中也有一个,叫任务栈,用来维护Activity的
栈这个结构,就是先进后出。
TaskStack
有一点要记住,activity可以自己开启自己,也就是在栈里面可能是这个效果A-B-A-A-A,这个时候就要按5次返回按钮退出应用。有了这个概念,下面再说四种启动方式和区别

第一种模式:android:launchMode=“standard” 这个是标准模式,也是默认启动模式。

就是只要你开启一个Activity,任务栈中就多一个Activity。开启几个activity,想要退出,就要按几次返回按钮。

第二种模式:android:launchMode=“singleTop” 这个模式叫栈顶唯一。

一般浏览器的书签页面就是这个启动模式
Android开发者网站写的太官方了,有点不好理解,通俗点讲,如果有两个activity,A和B,B设置的启动模式是singleTop,如果栈里已存在的activity是这样的,A-B-A,这个时候如果A还想开启自己,那么,就会调用onNewIntent方法,并不会创建A这个activity的实例。最后还是A-B-A,按3次返回退出应用。

第三种模式:android:launchMode=“singleTask” 这个模式叫栈内唯一。

一般浏览器的浏览页面就是这个模式。
通俗的说一下,两个activity,A和B,假设栈内已经是A-B-A-A-A-A这个情况了,这个时候你在开启B的时候,系统就会先检查任务栈内是否存在这个实例了,如果存在就把A-A-A-A这四个activity销毁掉,然后调用onNewIntent方法,并不会创建新的B实例。也就变成了A-B两个了,按两次返回就退出应用了。这样说应该能理解吧。

第四种模式:android:launchMode="singleInstance"这个模式叫单一实例模式。并且这个页面可以被共享。

打电话的页面就是这个模式,还有在做保活的时候需要使用。使用一像素保活,需要使用这个模式。
这个模式是什么情况呢,假设你有一个任务栈A-B-D-S-B这种情况。如果这个时候你想启动C,而C设置了这个模式,那么系统会单独为C开一个任务栈,而这个任务栈中只有一个C,并且C也不能创建多个自己,如果你在开启B的时候,系统会把A-B-D-S-B这个任务栈拿过来,把C这个任务栈置后,这时候操作的时候其实移动的是任务栈,并不是activity了。如果你销毁了C,那么C存在的这个任务栈,也会被销毁。

开启Activity的两种方式

开启一个activity有两种方式,一种是显示开启,一种是隐式开启。

显示开启

如下代码,直接指定类名点class开启页面

		//这样就是显示开启
        Intent intent = new Intent(this,Main2Activity.class);
        startActivity(intent);
        
        //还有一种显示开启activity的方式,
		Intent intent = new Intent();
		//这里的参数packageName就是包名,className是类名,都是字符串
		//这里的包名和类名一定要写对,写完整。
		intent.setClassName(packageName,className);
		startActivity(intent);

隐式开启

就是指使用意图过滤器开启

			//拨打电话这个就是隐式开启
			// 手机号
			String phone = "12344567345";
            Intent intent = new Intent();//创建一个意图
            intent.setAction(Intent.ACTION_CALL);//设置活动
            intent.setData(Uri.parse("tel:"+phone));//设置数据
            startActivity(intent);//开启意图 拨打电话
        如果是自己的activity怎么弄呢
        就是在清单文件中设置意图过滤器
            <activity android:name=".Main2Activity">
            	<!--意图过滤器-->
            	<intent-filter>
                	<action android:name="android.intent.action.Main2"/>
                	<category android:name="android.intent.category.DEFAULT"/>
            	</intent-filter>
        	</activity>
    	// 如果是如上配置
    	// 按照如下代码去写就能开启Main2Activity了
        	//如果你需要加data,像拨打电话那样,自己在意图过滤器中添加data
        	Intent intent = new Intent();
	        intent.setAction("android.intent.action.Main2");
	        intent.addCategory("android.intent.category.DEFAULT");
	        startActivity(intent);

如果你想弄一个比较复杂的意图过滤器,可以这样写

<activity android:name=".Main2Activity">
        <!--意图过滤器-->
        <intent-filter>
              <action android:name="android.intent.action.Main2"/>
              <category android:name="android.intent.category.DEFAULT"/>
              <data android:mimeType="abcd/hahaha"/>
              <data android:scheme="learn"/>
          </intent-filter>
</activity>

上面这样写应该怎么隐式启动呢,看如下代码

		Intent intent = new Intent();
        intent.setAction("android.intent.action.Main2");
        intent.addCategory("android.intent.category.DEFAULT");
        //如果type和Data存在的话,就不能像如下这种方式单独设置了
        //需要使用setDataAndType方法来开启activity
//        intent.setType("abcd/hahaha");
//        intent.setData(Uri.parse("learn:"+452345));
        intent.setDataAndType(Uri.parse("learn:"+452345),"abcd/hahaha");
        startActivity(intent);

总结,如果不使用意图过滤器开启Activity,就叫显示开启。使用意图过滤器开启Activity,就叫隐式开启。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值