一、Activity介绍
Activity是android四大组件之一(四大组件:activity、Service、Broadcast Receivers、Content Providers),主要用在视图层既我们所看见的界面窗口。
二、Activity的创建
第一步:定义一个java类让它继承Activity
第二步:在清单文件(AndroidManifest.xml)中配置activity的标签
<activity
android:name="com.itheima.activityjump.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
三、Activity的跳转
Activity的跳转分为:显式跳转和隐式跳转
显示跳转:
//显式启动SecondActivity
public void click2(View v){
//这个是显式意图
Intent intent = new Intent();
//设置上下文和目标Activity的字节码
intent.setClass(this, SecondActivity.class);
startActivity(intent);
}
//显式启动拨号器
public void click3(View v){
Intent intent = new Intent();
//arg0:目标Activity所在的应用的包名
//arg1:目标Activity的类名,注意要带上包名
intent.setClassName("com.android.dialer", "com.android.dialer.DialtactsActivity");
startActivity(intent);
}
/**
* 显式启动浏览器
*/
public void click6(View v){
Intent intent = new Intent();
intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity");
startActivity(intent);
}
隐式跳转:
//隐式跳转至打电话Activity
public void click1(View v){
//创建意图,这个是隐式意图
Intent intent = new Intent();
//设置动作
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:110"));
//启动Activity
startActivity(intent);
}
/**
* 隐式启动浏览器
*/
public void click7(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http:www.baidu.com"));
startActivity(intent);
}
自定义隐式跳转:
清单文件(AndroidManifest.xml)中配置activity的intent-filter(Intent文件过滤器)
<action android:name="a.b.c"/>
action的名称(可以多个)
<data android:scheme="heima"/>
数据协议名,如上,要求传递的数据开头必须是”heima"
<data android:scheme="heima3" android:mimeType="text/name"/>
数据协议名,如上,要求传递的数据开头必须是”heima"
数据的类型是字符串是自己定义的
<category android:name="android.intent.category.DEFAULT"/>
Category是对目标组件类别信息的描述。同样作为一个字符串对象,一个Intent中可以包含多个Category。与Category相关的方法有三个
启动这个activity必须要,action,data,Category相同才能启动。
第一个案例:
清单文件(AndroidManifest.xml)中配置
<activity android:name=".SecondActivity">
<intent-filter >
<action android:name="a.b.c"/>
<data android:scheme="heima"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
启动代码:
/**
* 隐式启动SecondActivity
*/
public void click5(View v){
Intent intent = new Intent();
intent.setAction("a.b.c");//和intent-filter中的android:name一致
//匹配scheme
intent.setData(Uri.parse("heima:春眠不觉晓"));//和intent-filter中的android:scheme一致
//如果没有设置Category的匹配,那么自动匹配CATEGORY_DEFAULT
// intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
}
第二个案例:
清单文件(AndroidManifest.xml)中配置
<activity android:name=".SecondActivity">
<intent-filter >
<action android:name="a.b.c"/>
<action android:name="a.b.c3"/>
<data android:scheme="heima"/>
<data android:scheme="heima3" android:mimeType="text/name"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter >
<action android:name="a.b.c2"/>
<data android:scheme="heima2"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
启动代码:
/**
* 隐式启动SecondActivity
*/
public void click5(View v){
Intent intent = new Intent();
intent.setAction("a.b.c");//和intent-filter中的android:name一致
intent.setDataAndType(Uri.parse("heima:春眠不觉晓"), "text/name");//当android:mimeType和android:scheme都存在,使用这个
//如果没有设置Category的匹配,那么自动匹配CATEGORY_DEFAULT
//intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
}
显式跳转和隐式跳转应用场合
显示跳转直接指明跳转到那个activity的。
隐式跳转是根据action等在对应清单文件(AndroidManifest.xml)中进行比对找到相应的activity的进行启动。
启动同一应用中的Activity,用显式。因为显示跳转效率比隐式跳转高。
启动不同应用中的Activity,用隐式。如果系统找到了多个intent-filter与程序员创建的intent匹配,那么就会弹出对话框,列举所有匹配的Activity,让用户选择。
四、Activity的跳转数据传递-将数据封装在Intent中
利用Extra进行保存
Intent intent = new Intent(this, SecondActivity.class);
//把数据封装至intent中
//intent中可以封装数据,数据有八大基本数据类型和字符串及它们的数组,还有实现了序列化接口的对象,还有bundle对象
intent.putExtra("maleName", maleName);
intent.putExtra("femaleName", femaleName);
startActivity(intent);
利用Extra进行取
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
String maleName = intent.getStringExtra("maleName");
String femaleName = intent.getStringExtra("femaleName");
}
利用Bundle进行存储
public void click(View v){
EditText et_malename = (EditText) findViewById(R.id.et_malename);
EditText et_femalename = (EditText) findViewById(R.id.et_femalename);
String maleName = et_malename.getText().toString();
String femaleName = et_femalename.getText().toString();
Intent intent = new Intent(this, SecondActivity.class);
//把数据封装至intent中
//Bundle中也可以用键值对封装数据,封装类型与intent一致
Bundle extras = new Bundle();
extras.putString("maleName", maleName);
extras.putString("femaleName", femaleName);
intent.putExtras(extras);
startActivity(intent);
}
利用 Bundle进行取
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String maleName = bundle.getString("maleName");
String femaleName = bundle.getString("femaleName");
}
}
五、Activity的生命周期
1.onCreate(Bundle bundle)方法:当这个Activity是第一次调用时候,执行onCreate方法,一般在这个方法中初始化一些按键、添加监听等
2.onStart()方法:当你能够看见这个activity的界面时候,执行onStart()方法(没有获取到焦点)
3.onResume()方法:当你这个activity的界面获取焦点的时候,执行了onResume()方法(获取到焦点)
4.onPause()方法:当有另一个activity执行时候,当前的activity会执行onPause()方法,将当前的activity中使用的信息保留下来(失去焦点)
5.onStop()方法:当有另外一个activity执行时候且activity运行的界面完全挡住了当前activity的界面执行这个方法。
6.onDestroy()方法:有两种情况:a).当我们主动在activity中调用finish()方法,调用onDestroy()方法。b).系统资源不够的时候,会调用级别较低的onDestroy()方法进行销毁。
7.onRestart()方法:当有另外一个activity执行时候且activity运行的界面完全挡住了当前activity的界面执行onStop()方法,当你又返回到这个界面时候执行了onRestart()方法。
Activity的执行转换图:
六、Activity的四种启动模式
启动模式有4种,分别为standard、singleTop、singleTask、singleInstance;
七、横竖屏切换
默认情况横竖屏切换会触发生命周期方法重新执行,Activity销毁重建
* 用以下代码让横竖屏切换时不重建Activity
android:configChanges="orientation|screenSize|keyboardHidden"
* 用以下代码写死屏幕方向
android:screenOrientation="portrait"
八、Activity摧毁时返回数据
如果你想在Activity中得到新打开Activity关闭后返回的数据,你需要使用Activity提供的startActivityForResult(Intent intent,int requestCode)(startActivity()是context提供的抽象方法,而startActivityForResult方法是Activity自己特有的方法)方法打开新的Activity,新的Activity关闭后会向前面的Activity 传回数据,为了得到传回的数据,你必须在前面的Activity中重写onActivityResult(int requestCode, intresultCode, Intent data)
案例:
public class MainActivity extends Activity {
public static final int CONTACT = 10;
public static final int SMS = 20;
public static final int HANDLE_EXCEPTION = 30;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View v){
Intent intent = new Intent(this, ContactActivity.class);
//启动一个Activity去获取数据(结果)
startActivityForResult(intent, CONTACT);
}
public void click2(View v){
Intent intent = new Intent(this, SmsActivity.class);
startActivityForResult(intent, SMS);
}
public void click3(View v){
Intent intent = new Intent(this, HandleExceptionActivity.class);
startActivityForResult(intent, HANDLE_EXCEPTION);
}
//只有通过startActivityForResult启动的Activity销毁时,才会回调这个方法,方法中传入的intent就封装了返回的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//通过请求码来判断data来自哪一个Activity
if(requestCode == CONTACT){
String name = data.getStringExtra("name");
EditText et_name = (EditText) findViewById(R.id.et_name);
et_name.setText(name);
}
else if(requestCode == SMS){
String sms = data.getStringExtra("sms");
EditText et_content = (EditText) findViewById(R.id.et_content);
et_content.setText(sms);
}
//先通过请求码判断data来自哪个Activity
else if(requestCode == HANDLE_EXCEPTION){
//通过结果码判断数据data中的数据是什么类型
if(resultCode == 100){
String name = data.getStringExtra("name");
EditText et_name = (EditText) findViewById(R.id.et_name);
et_name.setText(name);
}
else if(resultCode == 200){
String sms = data.getStringExtra("sms");
EditText et_content = (EditText) findViewById(R.id.et_content);
et_content.setText(sms);
}
}
}
}
public class ContactActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
final String[] names = new String[]{
"春晓",
"苗润",
"爱的结晶"
};
//显示联系人列表
ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.item_listview, R.id.tv, names));
lv.setOnItemClickListener(new OnItemClickListener() {
//position:点击某个条目时,会通过position告诉程序员点击的是哪一个条目
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent data = new Intent();
//把要传递的数据封装至intent中
data.putExtra("name", names[position]);
//当此Activity销毁时,返回至上一个Activity时,会把这个intent对象传递给上一个Activity
setResult(10, data);
//销毁当前Activity
finish();
}
});
}
}
public class SmsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
final String[] smss = new String[]{
"我正在开会,一会回你",
"我正在7饭,一会回你",
"我已死,有事烧纸"
};
//显示联系人列表
ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.item_listview, R.id.tv, smss));
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent data = new Intent();
data.putExtra("sms", smss[position]);
setResult(20, data);
finish();
}
});
}
}