一、认识Activity组件
Activity是Android 四大基本组件之一,可以通过 setContentView 方法绑定一个布局用于呈现界面与用户进行交互,是 Android 开发必不可少的学习内容。
二、Activity生命周期
三、在Activity之间传递参数
- 传递简单数据
新建工程SendArgs,给activity_main.xml添加一个Button:
<Button
android: id = "@+id/btnStartAty"
android: text = "启动另一个Activity" />
新建一个Activity名为TheAty,在TheAty.java的onCreate()添加:
Intent i = getIntent();
tv = (Text View) findViewById(R.id.tv);
tv.setText(i.getStringExtra("data");
修改activity_the_aty.xml:
<TextView
android:text = "hello lin!"
android:id = "@+id/tv" />
在MainActivity.java的onCreate()中添加:
findViewById(R.id.btnStarAty).setOnClickListener(new View.OnclickListener()
{
@override
public void onClick(View v){
Intent i = new Intent(MainActivity.this,TheAty.class);
i.putExtra("data", "come on!");
startActivity(i);
}
}
运行启动,点击启动另一个Activity就可以看到跳出另一个Activity并且文本显示come on!
。
- 传递复杂数据(数据包)
还是之前的工程,修改MainActivity.java按钮事件监听器的代码:
public void onClick(View v){
Intent i = new Intent(MainActivity.this, TheAty.class);
Bundle b =new Bundle();
b.putString("name", "lin");
b.putInt("age", 23);
i.putExtras(b); // 方式1
i.putExtra("data", b); // 方式2
startActivity(i);
}
修改TheAty.java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_the_aty);
Intent i = getIntent();
Bundle data = i.getExtras(); // 方式1
Bundle data = i.getBundleExtra("data"); // 方式2
tv = (TextView) findViewById(R.id.tv);
tv.setText(String.format("name=%s, age=%d, name1=%s", data.getString("name"), data.getInt("age"), data.getString("name1", "leo")));
}
运行启动,点击启动另一个Activity就可以看到跳出另一个Activity并且文本显示name=lin,age=23,name1=leo
。
- 传递自定义值对象
新建一个类User.java,序列化对象接口Serializable(java内部提供)和Parcelable(Android提供):
public class User implements Serializable // Parcelable
{
private String name;
Private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User(String name, int age){
this.name = name;
this.age = age;
}
}
还是之前的工程,修改MainActivity.java按钮事件监听器的代码:
public void onClick(View v){ {
Intent i = new Intent(MainActivity.this, TheAty.class);
i.putExtra("user", new User("lin",23));
startActivity(i);
}
修改TheAty.java:
protected void onCreate(Bundle savedInstanceState) {
Intent i = getIntent();
tv = (TextView) findViewById(R.id.tv);
User user = (User) i.getSerializableExtra("user");
//User user = (User) i.getParcelableExtra("user");
tv.setText(String.format("User info(name=%s, age=%d)", user.getName(), user.getAge()));
}
运行启动,点击启动另一个Activity就可以看到跳出另一个Activity并且文本显示User info(name=lin, age=23)
。
接下来使用Parcelable,修改User.java:
public class User implements Parcelable
{
//其他不变
}
// 新添两个方法
@Override
public int describeContents() {
return 0;
}
@Overrride
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(getName());
dest.writeInt(getAge());
}
public static final Creator<User> CREATOR = new CREATOR<User>() {
@Override
public User createFromParcel(Parcel source) {
return new User(source.readString(), source.readInt());
}
@Overrride
public User newArray(int size) {
return new User[size];
}
};
运行启动,点击启动另一个Activity就可以看到跳出另一个Activity并且文本显示User info(name=lin, age=23)
。
四、Activity启动模式
在Android中Activity有四种启动模式. 每一种模式都代表着一种使用场合. 对四种启动模式有深入的了解才能在实际开发工作中得心应手,写出完美的程序.
- 标准启动模式(默认的启动模式)
新建工程LauchMode,为activity_main.java中的<TextView>添加id:
<TextView
android:id="@+id/tv" />
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
tv.setText(String.format("TaskID:%d\nCurrent Activity id:%s",
getTaskId(), toString())); // 任务栈的id和当前实例的id
}
}
运行结果:
TaskID:1950
Current Activity id:com.lin.lauchmode.MainActivity@8695dad
之后更改布局
<LinearLayout>
android:orientation="vertical"
</LinearLayout>
然后拖进一个Button
<Button
android:textAllCaps="false" //不要字母都大写
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动MainActivity" //启动自己
android:id="@+id/btnStarSelf" />
回到MainAcyivity.java在OnCreate()添加按钮的事件监听器:
findViewById(R.id.btnStarSelf).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, MainActivity.class));
}
});
运行结果:
TaskID:1952
Current Activity id:com.lin.lauchmode.MainActivity@89806
点击一下Button:
TaskID:1952
Current Activity id:com.lin.lauchmode.MainActivity@f3232c0
可以看到TaskID
是一样的,而后面的id
是不一样的.也就是说此时所启动的程序在同一个任务栈里边,只是创建不同的实例而已.每当点击btn都会新创建出一个实例并放入任务栈中,后退又会回到之前的实例.也就是栈的作用,先进后出.通过这种方式可以支持后退键的导航.
在 AndroidMainfest.xml中更改启动模式
<application>
<activity
android:name=".MainActivity"
android:lauchMode="standard" /> //默认
</application>
- SingleTop模式
修改AndroidMainfest.xml
<application>
<activity
android:name=".MainActivity"
android:launchMode="singleTop">
</activity>
</application>
运行结果:
TaskID:1954
Current Activity id:com.lin.lauchmode.MainActivity@89806
点击btn
,文本没有丝毫变化,按回退键,程序退出.
接下来在创建一个Activity
BAty.
activity_baty.xml
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv" //同个文件id不可相同,反之可以
android:text="Hello World!" />
BAty.java
public class BAty extends AppCompatActivity {
private TextView tv; // add
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_baty);
tv = (TextView) findViewById(R.id.tv); //add
tv.setText(String.format("TaskID:%d\nCurrent Activity id:%s",
getTaskId(), toString())); // add 任务栈的id和当前实例的id
}
在A里面再添加一个按钮
<Button
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动MainActivity"
android:id="@+id/btnMainAty" /> // shit+f6改
<Button
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动BAty"
android:id="@+id/btnStartBaty" />
回到MainActivity.java,再写一个监听器
findViewById(R.id.btnStarBAty).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, BAty.class));
}
});
最后将activity_main.xml的内容拷贝到activity_baty.xml中.两个一样,然后将MainActivity.java的两个监听器拷贝到BAty.java.
修改当前启动的activity
startActivity(new Intent(BAty.this, BAty.class));
运行结果:
TaskID:1957
Current Activity id:com.lin.lauchmode.MainActivity@bc0e17f
按下启动MainActivity按钮,文本无改变.
按下启动BAty进入BAty,再按下启动MainActivity,注意此时的实例id改变:MainActivity@c4f080d
.
singleTop
意义: 也就是说在同一个栈里面指明singleTop模式下,当前实例位于栈顶时不会创建新的实例,反之可以.
- SingleTask与SingleInstance模式
首先在修改AndroidMainfest.xml:
android:launchMode="singleTask"
运行结果:
TaskID:1960
Current Activity id:com.lin.lauchmode.MainActivity@bc0e17f
此时有一个任务栈,它的id为1960,然后这个任务栈里面有了一个activity是MainActivity.然后启动BAty,此时这个任务栈里面有了两个activity.第一个是MainActivity,第二个是BAty.然后此时我们启动MainActivity的话,它会把BAty给弹出.弹回到第一个activity实例,此时我们在摁后退键的话,程序就会退出------这就是singleTask
的意义。
接下来我们修改AndroidMainfest.xml:
android:launchMode="singleInstance"
运行结果:
TaskID:1961
Current Activity id:com.lin.lauchmode.MainActivity@bc0e17f
启动MainActivity,没有变化,因为是同一个实例同一个任务栈.
启动BAty,可以看到BAty的TaskID:1962
,已经不是同一个栈了.
也就意味着singleInstance
只存在一个独立的任务栈里边,一个任务栈只包括这么一个activity.
反复点击两个按钮,你会发现两个actyvity在相互切换。
网友评论