Android第一行代码——(第二章)探究活动

1、Activity活动

活动是一种可以包含用户界面的组件,主要用于和用户进行交互。

创建活动时需要注意是否勾选Generate Layout FileLauncher Activity

项目中任何活动都应该重写onCreate方法

  • protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
  • setContentView()方法给当前的活动加载布局,可传入一个布局文件的id。

2、Manifest文件

AndroidManifest文件中注册:

  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.activitylifecycletest">
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity"
                      android:label="This is MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    
  • <action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/>用于配置主活动

  • android:label不仅会成为标题栏中的内容,还会成为启动器中应用程序显示的名称。

3、Toast消息窗

Toast是安卓提供的很好的提醒方式,可以将短小的信息通知给用户。

  • Toast.makeText(this, "message", Toast.LENGTH_SHORT).show();
    
  • 第一个参数为context,即Toast的上下文,可传入活动作为context对象;第二个参数为显示内容;第三个参数为显示时间。

4、Menu菜单

Menu能在标题栏中提供菜单选项

  • res目录下新建Directory,命名为menu

  • menu文件夹下新建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>
    
  • 在活动代码中重写onCreateOptionsMenu()方法:

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

    getMenuInflater方法能得到MenuInflater对象,再调用inflater方法可以给当前活动创建菜单。

  • 在活动中重写onOptionItemSelected方法,定义菜单响应事件:

    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.add_item: {
                    Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();
                    break;
                }
                case R.id.remove_item: {
                    Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show();
                    break;
                }
                default:
                    break;
            }
            return true;
    }
    

销毁活动finish()方法

5、Intent活动跳转

Intent的两种实现方式

  • 显式Intent:Intent(Context packageContext,Class<?>cls)。Intent构建后运行startActivity启动活动。

    button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                    startActivity(intent);
                }
     });
    
  • 隐式Intent:指定了一系列抽象的actioncategory

    <activity>下配置<intent-filter>

    <activity android:name=".SecondActivity">
        <intent-filter>
            <action android:name="com.example.activityTest.ACTION_START"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>
    

    category标签包含了一些附加信息,更精确地指明当前的活动能够响应的Intent中可能带有的category

    只有action和category中内容能够同时匹配Intent中的action和category时,该活动才能响应该Intent。

    活动中的隐式Intent写法:

    Intent intent=new Intent("com.example.activityTest.ACTION_START");
    

    一个Intent只能有一个action,但是可以指定多个category,通过下列方式增加category:

    intent.addCategory("com.example.activityTest.MY_CATEGORY");
    

    同时,在Manifest文件中应该添加category的声明:

    <category android:name="com.example.activityTest.MY_CATEGORY">
    

隐式Intent不仅可以启动自己程序内的活动,也可以启动其他程序的活动,以浏览器为例:

  • Activity中添加:

    Intent intent =new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse("http://www.baidu.com"));
    
    • Intent.ACTION_VIEW是安卓系统内置的动作,其值为android.intent.action.view
    • Uri.parse将网址解析成Uri对象,再调用Intent的setData方法把Uri对象传递进去。
  • Manifest中添加:

    <action android:name="android.intent.action.VIEW"/>
    
  • <intent-filter>中可添加<data>标签,用于更精确地指定当前活动能够响应什么类型的数据

    android:scheme         指定数据的协议
    android:host	      指定数据的主机名部分
    android:port	      指定数据的端口部分
    android:path	     指定主机名和端口之后的部分
    android:mimeType    指定可以处理的数据类型,允许使用通配符的方式指定
    

    只有<data>标签中指定的内容与Intent中携带的Data完全一致时,才能响应该Intent。

5.1、向下一个活动传递数据

Intent中提供了一系列putExtra()方法的重载,可将数据暂存在Intent中,跳转到下一个活动中可从中提取出:

  • 本活动中传数据:

    intent.putExtra("key", value);    // "key"为数据的键,value为数据的值
    
  • 下一个活动中提取数据:

    Intent intent=getIntent();
    String str=intent.getStringExtra("key");  // getIntExtra, getBooleanExtra...
    
5.2、向上一个活动返回数据

Activity中startActivityForResult()可用于启动活动,并在活动销毁时将一个结果返回给上一个活动。

srartActivityForResult方法接收两个参数,第一个参数为Intent,第二个参数为请求码,用于之后的回调中判断数据的来源。

本活动中设置跳转动作:

startActivityForResult(intent, 1);

下一个活动中需要设置返回的结果:

intent.putExtra("return", value);
setResult(RESULT_OK, intent);    // RESULT_OK或RESULT_CANCELED
finish();

本活动中需要重写回调的onActivityResult方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
    switch(requestCode){
        case 1:
            if(resultCode==RESULT_OK){
                ...
            }
            break;
        default:
            break;
    }
}
// 首先检查requestCode判断数据来源,再检查resultCode判断数据处理是否成功

如果想要用户点击返回键而不是特定按钮返回上一个活动,则需要在下一个活动中重写onBackPressed方法:

@Override
public void onBackPressed(){
    Intent intent =new Intent();
    intent.putExtra("return", value);
    setResult(RESULT_OK, intent);
    finish();s
}

6、活动的生命周期

返回栈,一个任务就是一组存放在栈里的活动的集合。

生命周期的四个状态:

  • 运行:活动位于返回栈的栈顶
  • 暂停:活动不处于栈顶,但仍然可见
  • 停止:活动不处于栈顶,且完全不可见
  • 销毁:活动从栈中移除

Activity的7个回调方法:

  • onCreate:活动创建的时候调用
  • onStart:活动由不可见变为可见时调用
  • onResume:活动准备好与用户进行交互时调用
  • onPause:启动或回复另一个活动时调用
  • onStop:活动完全不可见时调用
  • onDestroy:活动销毁前调用
  • onRestart:活动由停止转为运行前调用

3个生存期

  • 完整生存期:onCreate()~onDestroy()
  • 可见生存期:onStart()~onStop()
  • 前台生存期:onResume()~onPause()

避免因活动被回收导致关键数据丢失:onSaveInstanceState()

  • 重写onSaveInstanceState方法

    @Override
    protected void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        String value="value";
        outState.putString("key",calue);
    }
    
  • 修改onCreate方法

    if(savedInstanceState!=null){
        String value=savedInstanceState.getString("key");    // getString, getInt...
        ...
    }
    

Intent可以结合Bundle一起用于传递数据。将需要传递的数保存在Bundle对象中,然后将Bundle对象存放在Intent内;在目标活动中先从Intent中取出Bundle,再从Bundle中取出数据。

7、活动的启动模式

实际项目中应该为每个活动指定恰当的启动模式。

在Manifest文件中通过给<activity>指定android:launchMode选择启动模式。

启动模式有4种:

  • standard:活动的默认启动模式。每当启动一个新的活动,它就会在返回栈内入栈,并位于栈顶。每次启动都会创建该活动的一个实例(无论栈中是否已经有此活动)。
  • singleTop:在启动活动的时候如果返回栈的栈顶已经是该活动,则可以直接使用它,不会再创建新的活动实例。如果活动实例不在栈顶,则仍然会创建新的实例。
  • singleTask:创建实例之前,会检查返回栈的元素。如果返回栈中存在该活动的实例,则直接使用该实例并把这个活动之上的所有活动全部出栈;如果不存在则创建新的实例。
  • singleInstance:此模式的活动会启用一个新的返回栈来管理这个活动。此模式可解决不同应用程序共享活动实例的问题。

8、活动的设计技巧

知晓是当前是哪个活动:

  • 新建BaseActivity类:不同于新建一个活动,只新建一个Java类继承于AppcompatActivity,并重写onCreate方法:

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity", getClass().getSimpleName());
    }
    
  • 其他的活动继承于BaseActivity类:当新建一个活动实例时日志会打印这个活动的名称。

随时随地退出程序:

  • 新建一个ActivityCollector类作为活动管理器

    public class ActivityCollector{
        public static List<Activity> activities=new ArrayList<>();
        
        public static void addActivity(Activity activity){
            activities.add(activity);
        }
        
        public static void removeActivity(Activity activity){
            activities.remove(activity);
        }
        
        public static void finnishAll(){
            for(Activity activity:activities){
                if(!activity.isFinishing){
                    activity.finish();
                }
            }
        }
        
    }
    
  • (可选)在销毁所有活动的代码后加上杀掉当前进程的代码android.os.Process.killProcess(android.os.Process.myPid());

启动活动的最佳写法:

  • 编写actionStart()方法

    public static void actionStart(Context context,String data1,String data2){
        Intent intent=new Intent(context,MyActivity.class);
        intent.putExtra("param1",data1);
        intent.putExtra("param2",data2);
        context.startActivity(intent);
    }
    
  • 好处:下一个活动所需参数全部体现,方便对接;简化代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值