Activity目录
小朋友你是不是有很多问号???
一、如何创建一个Activity
1、Android的四大组件都要在清单文件里面配置
2、如果你想让你的应用有多个启动图标,需要这样配置
<intent-filter>
<action android:name="android.intent.action.MAIN" /> //MAIN
<category android:name="android.intent.category.LAUNCHER" /> //LAUNCHER
</intent-filter>
3、Activity下的label和icon属性可以和Application节点的属性不一样;如果Activity中不写,则使用Application中的,否则使用Activity中写的。
4、一个Android应用一般我们就配置一个启动图标,看见的其他页面都是重第一个页面跳转过去的。
二、隐式意图
定义:通过指定一组动作或者数据
// 隐式意图
public void yin(View view) {
Intent intent = new Intent();
// 以下内容与AndroidManifest.xml中的intent-filter中的内容一一对应
// action
intent.setAction("android.intent.action.ZQ");
// category
intent.addCategory("android.intent.category.DEFAULT");
// scheme:约束条件:This method automatically clears any type that was previously set
//intent.setData(Uri.parse("zq:" + 110));
// mimeType:This method automatically clears any data that waspreviously set
//intent.setType("zq/bb");
// scheme和mimeType如果在AndroidManifest.xml中被同时定义了则使用这个方法
intent.setDataAndType(Uri.parse("zq:" + 110), "zq/bb");
startActivity(intent);
}
AndroidManifest.xml中的配置
<activity
android:name=".YinActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.ZQ" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:mimeType="zq/bb"
android:scheme="zq" />
</intent-filter>
</activity>
三、显示意图
定义:通过指定具体的包名和类名
//显示意图更加安全
public void xian(View view) {
//上下文和包名.class
Intent intent = new Intent(this, XianActivity.class);
//使用方法setClassName,包名和类名
//intent.setClassName("com.example.activity123","com.example.activity123.XianActivity");
startActivity(intent);
}
总结:1、开启自己应用的界面用显示意图
2、开启其他应用的界面(系统应用)用隐式意图
3、显示意图更加安全
四、人品计算器案例
1、发送数据
public void click(View view){
String name = et_name.getText().toString().trim();
if(TextUtils.isEmpty(name)){
Toast.makeText(this, "请输入姓名", 0).show();
return;
}
int id = rg_sex.getCheckedRadioButtonId();//获取被选中组件按钮的id
int type = 0;
switch (id) {
case R.id.nan://男人
type = 1;
break;
case R.id.nv://女人
type = 2;
break;
case R.id.yao://待定
type = 3;
break;
}
if(type==0){
Toast.makeText(this, "请选择性别", 0).show();
return;
}
Intent intent = new Intent(this,SecondActivity.class);
/**
* intent传递数据
*/
intent.putExtra("name", name);
intent.putExtra("type", type);
startActivity(intent);//打开第二个SecondActivity界面
}
2、接收数据
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取到激活当前activity的意图
Intent intent = getIntent();
/*
* 获得第一个页面传过来的数据
*/
String name = intent.getStringExtra("name");
// 第二个参数是defaultValue,如果获取不到该值,那么type默认为0
int type = intent.getIntExtra("type", 0);// 1.男人 2.女人 3.待定
byte[] result = null;
String sex = null;
try {
switch (type) {
case 1:
result = name.getBytes();// 将一个string类型的字符串转换成byte类型并且存入一个byte数组中。
sex = "【男】";
break;
case 2:
result = name.getBytes("gb2312");
sex = "【女】";
break;
case 3:
result = name.getBytes("iso-8859-1");
sex = "【人妖】";
break;
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (result != null) {
int score = 0;
for (byte b : result) {
score += (int) b;
}
int number = Math.abs(score) % 100;
TextView tv = new TextView(this);
if (number >= 90) {
tv.setText("计算完毕:\n" + name + sex + "的人品值为:" + number + "\n"
+ name + ",你的人品非常好,请继续保持!");
} else if (number >= 70) {
tv.setText("计算完毕:\n" + name + sex + "的人品值为:" + number + "\n"
+ name + ",你的人品还行,请继续加油");
} else if (number >= 60) {
tv.setText("计算完毕:\n" + name + sex + "的人品值为:" + number + "\n"
+ name + ",你的人品一般");
} else {
tv.setText("计算完毕:\n" + name + sex + "的人品值为:" + number + "\n"
+ name + ",你的人品太low了");
}
setContentView(tv);
}
}
五、短信大全案例
1、intent-filter
android系统中的拨打电话和发短信的intent-filter
1、拨打电话
intent.setAction(intent.ACTION_CALL);
// 5.2设置拨打的数据 tel:固定用法
//Uri:统一资源标识符,自定义路径 Url:统一资源定位符 www.baidu.com
intent.setData(Uri.parse("tel:" + 110));
//记得在配置文件中加上权限
<uses-permission android:name="android.permission.CALL_PHONE" />
2、发送短信
intent.setAction("android.intent.action.SEND");
intent.addCategory("android.intent.category.DEFAULT");
intent.setType("text/plain");
//name和系统接收的名字保持一致,去源码中寻找sms_body
intent.putExtra("sms_body", content);
总结:以上两个案例 A界面跳转到B界面 然后把A界面的数据传递到B界面
下面这个案例 A界面跳转到B界面 当B界面关闭的时候 把数据返回给A界面
六、短信发送器案例
数据回传
//发送信息的逻辑
public void send(View view) {
String phone = et_phone.getText().toString().trim();
String content = et_content.getText().toString().trim();
// 这个api收费,需要加权限
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> divideMessage = smsManager.divideMessage(content);
for (String div : divideMessage) {
/*
* destinationAddress 电话号码,发送给谁
* scAddress 服务中心号码 eg:中国移动
* text 短信内容
* sentIntent 发送成功的报告
* deliveryIntent 发送成功的报告
* null 就是默认
*/
smsManager.sendTextMessage(phone, null, div, null, null);
}
}
//点击item返回数据的逻辑
lv.setOnItemClickListener(new OnItemClickListener() {
// 可以通过debugger模式查看各个参数的含义
/*
* parent :ListView view:TextView
*/
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//这里有一个bug:当直接返回的时候程序会挂掉
String content = objects[position];
Intent intent = new Intent();
intent.putExtra("content", content );
// 把结果返回给调用者,通过onActivityResult这个方法
setResult(20, intent);//结果码,为int类型
// 关闭当前页面数据返回
finish();
}
});
// 当我们开启的activity关闭的时候,调用这个方法onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == 2) {// 代表数据来自XxBuyActivity
// 取数据
Info info1 = (Info) data.getExtras().get("info1");
// 更新一下UI
updateProgressBar(info1);
}
if (resultCode == 1) {// 代表数据来自HostBuyActivity
// 取数据
Info info = (Info) data.getExtras().get("info");
// 更新一下UI
updateProgressBar(info);
}
super.onActivityResult(requestCode, resultCode, data);
}
模拟器不支持中文短信发送,会乱码;且中文字符不得超过70,英文不得超过140个字符
七、Activity的生命周期
有五种状态:启动,运行,暂停,停止,销毁
1、什么是生命周期
java代码:对象的生命周期
activity生命周期:对象从new出来到被Dalvik虚拟机回收的过程中执行的方法
2、生命周期的重要方法
onCreate:activity被创建的时候调用,如果activity已经被创建不会重复执行
onDestroy:activity被销毁的时候调用。代码执行finish(),或者用户点击了手机的返回键(点击home键不会被销毁)。适合做扫尾操作,数据保存的操作。
onStart:activity界面用户可见时调用。适合更新界面(继续播放视频)
onStop:activity界面用户不可见时调用。适合清理操作(暂停播放视频)
onResume:获取焦点,按钮可以被点击
onPause:失去焦点,按钮可以看见,但是不可以被点击。
2.1、完整的生命周期
(Entire lifetime)
onCreate->onStart->onResume->onPause->onStop->onDestroy
2.2、可视生命周期
(visible lifetime)
onStart->onResume->onPause->onStop
tips:如果界面不可见,onStop方法,下次界面重新可见,先条用onRestart,再调用onstart
2.3、前台生命周期
(foreground lifetime)
onResume->onPause
3、横竖屏切换activity的生命周期
ctrl+F11 进行横竖屏切换
生命周期的变化为Entire lifetime的变化:onPause->onStop->onDestroy->onCreate->onStart->onResume
android:screenOrientation="portrait" //表示竖屏
android:screenOrientation="landscape" //表示横屏
八、android中的任务栈
1、任务栈
tips:一个应用程序默认是只有一个任务栈,特殊情况下,SingleInstance会有多个任务栈
什么是任务栈:任务栈是记录当前用户操作行为的一个数据结构,先进后出
2、进程
android系统,应用程序退出和进程退出是两个不同的概念。
android系统为了让应用程序可以被快速开启。所有的应用程序退出后,进程时不会退出的。只有系统的内存空间严重不足的时候,才会把进程给回收。
过程:点击图标->linux下创建进程->Dalvik虚拟机->读取清单文件,加载activity
在android下理解应用程序退出:任务栈被清空了。
3、线程
进程时操作系统分配内存空间的单位,每个进程的内存空间是独立的。
线程的运行在进程内,是cpu执行的最小单位,如果进程挂了,线程也就挂了
4、应用程序 application
(用java编写)
android应用程序每个应用程序都是运行在自己的sandBox(沙箱)中的。
理解成一组activity,service,provider,receiver等组件的组合。
九、Activity四种启动模式
1、Standard 标准的启动模式
一个activity默认就是标准的启动模式。开启新的activity,activity就会被创建出来,加入到任务栈的栈顶,适用于绝大多数的应用场景。
2、SingleTop 单一顶部启动模式
如果发现这个activity已经被启动了,并且在任务栈的栈顶,activity就不会被重新创建。
解决一个用户体验问题:避免已经打开的界面被重复多次打开,收藏夹。
3、SingleTask 单一任务栈启动模式
开启新的activity的时候,会去检查任务栈里面是否有这个activity的实例存在,如果有实例存在,就直接清空这个实例上面所有的activity,复用这个已经存在的activity实例。
在什么时候使用SingleTask模式?
eg:启动BrowserActivity,浏览器开销(内存占用,cpu占用)非常大,采用SingleTask启动模式保证在一个任务栈里面只有一个实例存在。
tips:BrowserActivity是由webkit(由c代码编写)内核页面完成。包括:
- html 解析器
- html 渲染器
- css 渲染器
- JavaScript 执行引擎
如果一个activity的资源开销非常大,建议使用singleTask的启动模式。浏览器的activity就是还是用的这种模式。
4、singleInstance 单一实例启动模式
类似于java中的单例模式,单态模式。在整个android手机操作系统里面只有一个activity实例存在。
singleInstance 启动模式的activity会运行在自己单独的任务栈里面。
eg:InCallScreen通话的activity配置模式就是singleInstance 的