四大组件之activity
本篇是Android四大组件之一的Activity一些基本的操作,Activity的生命周期。以及Intent,Activity间的数据传递的一些基本介绍。
创建一个新Activity
一个活动对应一个布局
活动
public class FirstActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
}
布局
在app/src/main/res目录下新建一个layout目录,然后在该目录下新建first_layout.xml布局文件
<LinearLayout xmlns:android="http://schema.android.com/aok/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
在活动里将布局引入进来
setContentView(R.layout.first_layout);
public class FirstActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
}
}
记得在AndroidManifest.xml里注册这个Activity
销毁Activity
在想要销毁的Activity内部使用finish();
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick (View v){
finish();
}
})
按button1这个按钮就可以销毁活动
Intent
显示Intent
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick (View v){
Intent intent = new Intent(FirstActivity.this,SecondAticity.class);
startActivity(intent);
}
})
隐式Intent
在AndroidManifest.xml为相应的Activity添加抽象的action和category信息,这些信息标注在他所处的Activity里的,在这里也就是SecondActivity
隐式Intent action
AndroidManifest.xml
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
FirstActivity.java
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick (View v){
Intent intent = new Intent("com.example.activitytest.ACTION_START");
startActivity(intent);
}
})
隐式Intent action+category
AndroidManifest.xml
<activity android:name=".SecondActivity">
<intent-filter>
<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>
FirstActivity.java
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick (View v){
Intent intent = new Intent("com.example.activitytest.ACTION_START");
intent.addCategory("com.example.activitytest.MY_CATEGORY")
startActivity(intent);
}
})
更多隐式Intent
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
})
在AndroidManifest.xml中修改ThirdActivity的intent-filter
AndroidManifest.xml
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:schema="http"/>
</intent-filter>
</activity>
添加了data android:scheme=”http”之后ThirdActivity可以响应action是Intent.ACTION_VIEW的常量值同时。他可以响应数据协议是http协议。这样的时候在FirstActivy中点击button1时
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
})
就会让我们在Browser和ActivityTest(含有ThirdActivity这个Activity的app)中二选一
除了http以外还有很多协议,geo表示显示地理位置,tel表示拨打电话
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
})
活动间数据传递
向下一个活动传递数据
Intent中提供了一些列的putExtra()方法的重载,这可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,再把这个数据从Intent中取出
在FirstActivity中,存入数据 ↓
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
String data = "Hello SecondActivity";
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("extra_data",data)
startActivity(intent);
}
})
在SecondActivity中 取出数据 ↓
public class SecondActivity extends AppCompatActivity{
@override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();
// getIntent()方法取到启动SecondActivity的Intent
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity",data);
}
}
返回数据给上一个活动
按Back键没有一个用于启动活动的Intent来传递数据
Activity有一个startActivityForResult()方法也是启动活动,但这个方法期望活动销毁的时候能返回一个结果给上一个活动
在FirstActivity(期望得到数据的Activity)中编写如下代码
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivityForResult(intent,1);
// 这个1是requestCode
}
})
这样点击button1就会用startActivityForResult()打开SecondActivity(打开这个Activity的目的就是为了它传数据回来)
SecondActivity传回数据的方法 ↓
public class SecondActivity extends AppCompatActivity{
@override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent();
//这个Intent仅仅是用于传递数据而已
intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK,intent);
//setResult()是关键方法,专门用于向上一个活动返回数据
finish();
}
})
}
}
由于我们是使用startActivityForResult()方法来启动SecondActivity的,在SecondActivity被销毁之后会回调上一个活动的onActivityResult()方法,因此我们需要在FirstActivity中重写这个方法来得到返回的数据,如下所示
@Override
protected void OnActivityResult(int requestCode,int resultCode,Intent data){
switch(requestCode){
case 1:
if(resultCode==RESULT_OK){
String returnedData = data.getStringExtra("data_return");
Log.d("FirstActivity",returnedData)
}
break;
default:
}
}
关于onActivityResult()
Activity的生命周期
活动状态
生命周期钩子
生命周期图
onSaveInstanceState()
Activity提供了一个onSaveInstanceState()回调方法,这个方法它可以保证活动在被回收之前一定会被调用。用来保存要被回收的活动的一些重要数据
保存
在MainActivity.java
@Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
String temData = "Something you just type";
outState.putString("data_key",temData);
}
读取
也在MainActivity.java
onCreate()方法其实也有一个Bundle类型的参数。这个参数在一般情况下都是null,但是如果在活动被系统回收之前有通过onSaveInstanceState()方法保存数据的话,这个参数就会带有之前保存的全部数据,我们只需要通过相应的取值方法取出即可
@override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
if(savedInstanceState != null){
String temData = savedInstanceState.getString("data_key");
Log.d("SecondActivity",temData)
}
}
Intent结合Bundle使用
Intent可以结合Bundle使用,一起用于传递数据。首先可以把需要传递的数据都保存在Bundle对象中,然后再将Bundle对象存放在Intent里。到了目标活动后先从Intent中取出Bundle。再从Bundle中一一取出数据
活动的启动模式
详细的就不写了
- standard
- singleTop
- singleTask
- singInstance