Android基础知识—Activity

一、认识Activity组件

Activity是Android 四大基本组件之一,可以通过 setContentView 方法绑定一个布局用于呈现界面与用户进行交互,是 Android 开发必不可少的学习内容。


二、Activity生命周期


三、在Activity之间传递参数

  1. 传递简单数据
    新建工程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!

  1. 传递复杂数据(数据包)
    还是之前的工程,修改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

  1. 传递自定义值对象
    新建一个类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有四种启动模式. 每一种模式都代表着一种使用场合. 对四种启动模式有深入的了解才能在实际开发工作中得心应手,写出完美的程序.

  1. 标准启动模式(默认的启动模式)
    新建工程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>
  1. SingleTop模式
    修改AndroidMainfest.xml
<application>
    <activity 
        android:name=".MainActivity"
        android:launchMode="singleTop">
    </activity>
</application>

运行结果:

TaskID:1954
Current Activity id:com.lin.lauchmode.MainActivity@89806

点击btn,文本没有丝毫变化,按回退键,程序退出.
接下来在创建一个ActivityBAty.

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模式下,当前实例位于栈顶时不会创建新的实例,反之可以.

  1. 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在相互切换。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358

推荐阅读更多精彩内容