第二章 探究活动(Activity)

2.1 活动是什么

活动(Activity)包含用户界面的组件,用于和用户进行交互。

2.2 Activity的基本用法

2.2.4 隐藏标题栏

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(window.FEATURE_NO_TITLE);
setContentView(R.layout.finrst_layout);
}

requesetWindow这句话是不显示标题栏,注意一定要在setContentView()之前执行,不然会报错。

2.2.5 Toast用法

Toast.makeText(FirstActivity.this,”YOU STUPID”,Toast.LENGTH_SHORT).show();
Toast用法简单,使用静态方法makeText(),创建一个Toast对象,然后调用show()显示即可。makeText()传入三个参数。第一个Context,也就是Toast要求的上下文;第二个是显示的内容;第三个显示时长。

2.2.6 Menu用法

在res目录下新建一个menu文件夹,在menu下新建Android菜单文件。
这里写图片描述

在main.xml中添加如下代码:

<menu xmlns:android="http://schemas.android.com/apk/res/android”>
        <item
            android:id="@+id/add_item"
            android:title="Add" />
        <item
            android:id="@+id/remove_item"
            android:title="Remove" />
</menu >      

这里创建了两个菜单项。在对应的Activity中重写onCreateOptionsMenu()方法

public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

通过getMenuInflater()方法能够得到MenuInflater对象,再调用它的inflate()方法就可以给当前的活动创建菜单了。inflate()接收两个参数,第一个用于指定我们通过哪一个资源文件来创建菜单;第二个用于指定我们菜单项将添加到哪一个Menu对象当中,这里用onCreateOptionsMenu()方法中传入的menu参数。然后返回true,表示允许菜单显示出来,否则菜单无法显示。
最后定义菜单响应事件,在Activity中重写onOptionItemSelected()方法:

   public boolean onOptionsItemSelected(MenuItem item){
     swith (item.getItemId() ) {
     case R.id.add_item;
     case R.id.remove_item;
     default:
     }
    return true;
   }

2.2.7 销毁一个活动

两个方法:一是通过Back方法;另外可以调用finish()方法。

2.3 使用Intent在活动之间穿梭

2.3.1 显示Intent

Intent有多个构造函数的重载,其中一个是Intent(Context packageContext,Class

2.3.2 隐式Intent

活动A跳转时,其他活动只要可以匹配A的action和category等信息,都可以跳转
活动A的代码如下:

button1.setOnClickListener(newOnClickListener(){
@Override
    publicvoidonClick(Viewv){
    Intentintent=newIntent("com.example.activitytest.ACTION_START");
startActivity(intent);
    intent.addCategory("com.example.activitytest.MY_CATEGORY");
    }
});

可以满足A跳转的B活动的定义为:

<activityandroid: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>

注意:每个Intent中只能指定一个action,但却能指定多个category。
A活动没有定义category也能到B活动,是因为B活动category中为android.intent.category.DEFAULT是一种默认的category,在调用
startActivity()方法的时候会自动将这个category添加到Intent中。

2.3.3 更多Intent用法

修改A活动,打开浏览器

button1.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewv){
Intentintent=newIntent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});

这里我们首先指定了Intent的action是Intent.ACTION_VIEW,这是一个Android系统内
置的动作,其常量值为android.intent.action.VIEW。然后通过Uri.parse()方法,将一个网址字
符串解析成一个Uri对象,再调用Intent的setData()方法将这个Uri对象传递进去。
与此对应,我们还可以在标签中再配置一个标签,用于更精确地指
定当前活动能够响应什么类型的数据。标签中主要可以配置以下内容。
1. android:scheme
用于指定数据的协议部分,如上例中的http部分。
2. android:host
用于指定数据的主机名部分,如上例中的www.baidu.com部分。
3. android:port
用于指定数据的端口部分,一般紧随在主机名之后。
4. android:path
用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
5. android:mimeType
用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
只有标签中指定的内容和Intent中携带的Data完全一致时,当前活动才能够响应
该Intent。不过一般在标签中都不会指定过多的内容,如上面浏览器示例中,其实只
需要指定android:scheme为http,就可以响应所有的http协议的Intent了。
除了http协议外,我们还可以指定很多其他协议,比如geo表示地理位置,tel表示打电话:

Intentintent=newIntent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);

2.3.4 向下一个活动传递数据

活动A向B中传入数据。A中实现代码如下:

Stringdata="HelloSecondActivity";
Intentintent=newIntent(FirstActivity.this,SecondActivity.class);
intent.putExtra("extra_data",data);
startActivity(intent);

注意这里putExtra()方法接收两个参数,第一个参数是键,用于后面从Intent
中取值,第二个参数才是真正要传递的数据。
在B中取出数据,并打印出来,如下:

Intentintent=getIntent();
Stringdata=intent.getStringExtra("extra_data");
Log.d("SecondActivity",data);

2.3.5 返回数据给上一个活动

Activity中还有一个startActivityForResult()方法也是用于启动活动的,启动活动销毁的时候能够返回一个结果给上一个活动。两个参数,一个是intent,第二个是请求码,用于在之后回调中判断数据来源。

Intentintent=newIntent(FirstActivity.this,SecondActivity.class);
startActivityForResult(intent,1);

在SecondActivity中添加返回数据逻辑:

Intentintent=newIntent();
intent.putExtra("data_return","HelloFirstActivity");
setResult(RESULT_OK,intent);
finish();

这里intent只用于传递数据,没有别的意图。然后调用了setResult()
方法。这个方法非常重要,是专门用于向上一个活动返回数据的。setResult()方法接收两个参数,第一个参数用于向上一个活动返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED这两个值,第二个参数则是把带有数据的Intent传递回去,然后调用了finish()方法来销毁当前活动。我们在第一个活动中天街代码来处理第二个活动传回来的数据,如下:

protected void onActivityResult(int requestCode,int resultCode,Intent data){
    switch(requestCode){
    case1:
        if(resultCode==RESULT_OK){
        StringreturnedData=data.getStringExtra("data_return");
        Log.d("FirstActivity",returnedData);
        }
        break;
    default:
    }
}

onActivityResult()方法带有三个参数,第一个参数requestCode,即我们在启动活动时传入的请求码。第二个参数resultCode,即我们在返回数据时传入的处理结果。第三个参数data,即携带着返回数据的Intent

2.4 活动的生命周期

2.4.3 活动的生存期

Activity类中定义了七个回调方法,覆盖了活动生命周期的每一个环节,下面我来一一
介绍下这七个方法。
1. onCreate()
这个方法你已经看到过很多次了,每个活动中我们都重写了这个方法,它会在活动
第一次被创建的时候调用。你应该在这个方法中完成活动的初始化操作,比如说加载布
局、绑定事件等。
2. onStart()
这个方法在活动由不可见变为可见的时候调用。
3. onResume()
这个方法在活动准备好和用户进行交互的时候调用。 此时的活动一定位于返回栈的
栈顶,并且处于运行状态。
4. onPause()
这个方法在系统准备去启动或者恢复另一个活动的时候调用。 我们通常会在这个方
法中将一些消耗 CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度
一定要快,不然会影响到新的栈顶活动的使用。
5. onStop()
这个方法在活动完全不可见的时候调用。它和 onPause()方法的主要区别在于,如
果启动的新活动是一个对话框式的活动,那么 onPause()方法会得到执行,而 onStop()
方法并不会执行。
6. onDestroy()
这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
7. onRestart()
这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。

2.4.5 活动被回收了怎么办

2.5 活动的启动模式

启动模式一共有四种,分别是 standard、singleTop、singleTask 和 singleInstance,可以在 AndroidManifest.xml 中通过给标签指定android:launchMode属性来选择启动模式。

2.6 活动的最佳实践

2.6.1 知晓当前是哪个活动

BaseActivity中重写 onCreate()方法,如下所示:

public class BaseActivity extends Activity {
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity", getClass().getSimpleName());
    }
}

我们在 onCreate()方法中获取了当前实例的类名,并通过 Log打印了出来。

2.6.2 随时随地退出程序

其实解决思路也很简单,只需要用一个专门的集合类对所有的活动进行管理就可以了。新建一个 ActivityCollector类作为活动管理器,代码如下所示:

public class ActivityCollector {
    public static List<Activity> activities = new ArrayList<Activity>();
    public static void addActivity(Activity activity) {
        activities.add(activity);
    }
    public static void removeActivity(Activity activity) {
        activities.remove(activity);
    }
    public static void finishAll() {
        for (Activity activity : activities) {
            if (!activity.isFinishing()) {
            activity.finish();
            }
        }
    }
}

在活动管理器中,我们通过一个 List来暂存活动,然后提供了一个 addActivity()方法用于向 List中添加一个活动,提供了一个removeActivity()方法用于从 List中移除活动,最后提供了一个 finishAll()方法用于将 List中存储的活动全部都销毁掉。接下来修改 BaseActivity中的代码,如下所示:

public class BaseActivity extends Activity {
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity", getClass().getSimpleName());
        ActivityCollector.addActivity(this);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

在 BaseActivity的 onCreate()方法中调用了 ActivityCollector的 addActivity()方法,表明将当前正在创建的活动添加到活动管理器里。然后在 BaseActivity中重写 onDestroy()方法,并调用了 ActivityCollector的 removeActivity()方法,表明将一个马上要销毁的活动从活动管理器里移除。然后在需要退出程序的地方添加如下代码即可:

ActivityCollector.finishAll();

当然你还可以在销毁所有活动的代码后面再加上杀掉当前进程的代码, 以保证程序完全退出。

2.6.3 启动活的的最佳写法(看懂了补充)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值