Android学习笔记(二)活动(Activity)

目录(?)[+]

2.活动(Activity)

2.1 概念

        活动是Android的基本组成单位,每个Activity都被定义为一个单独的类,且都继承自基类:android.app.Activity;它是一种包含用户界面的组件,主要用来与用户进行交互(通俗点讲,可以先理解为一个单独的屏幕、一个交互的窗口,但不完全是这样)。

2.2 基本使用


2.2.1 手动创建活动

        新建一个类FirstActivity,并继承自基类Activity,重写Activity的onCreate()方法(项目中的任何活动都要重写此方法)。
[java] view plain copy
  1. public class FirstActivity extends Activity {  
  2.   
  3.         @Override  
  4.         protected void onCreate(Bundle savedInstanceState) {  
  5.             super.onCreate(savedInstanceState);  
  6.         }  
  7.     }  

2.2.2 创建加载布局

       Android应用讲究逻辑和视图分离,所以最好一个Activity对应一个XML布局文件。
        创建activity_first.xml文件(在res-->layout目录下),并添加一个按钮:
[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical">  
  6.   
  7.     <!--  
  8.     android:id==>>给当前的元素定义一个唯一标识符,可在代码中调用。  
  9.     @+id/btn_1==>>需要引用一个id,则使用@id/id_name这种语法;需要定义一个id,则使用@+id/id_name这种语法,其他资源一致。  
  10.     android:layout_width==>>指定当前元素宽度,同理height为高度  
  11.     android:text==>>指定元素显示的文字内容,其实文字应该放在字符串文件中并在这里引用。  
  12.     -->  
  13.   
  14.     <Button  
  15.         android:layout_width="wrap_content"  
  16.         android:layout_height="wrap_content"  
  17.         android:text="Button"  
  18.         android:id="@+id/btn_1" />  
  19.   
  20. </LinearLayout>  
在代码中调用此视图显示到activity中:
[java] view plain copy
  1. setContentView(R.layout.activity_first);  
这里我们使用自己的R文件,AndroidSDK还会提供一个android包下的R文件,不要弄错。

2.2.3 在Androidmanifest.xml中注册

所有的活动都要在AndroidManifest.xml中进行注册才能生效:
[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.jastar.activitytest">  
  4.   
  5.     <application  
  6.         android:allowBackup="true"  
  7.         android:icon="@mipmap/ic_launcher"  
  8.         android:label="@string/app_name"  
  9.         android:supportsRtl="true"  
  10.         android:theme="@style/AppTheme">  
  11.         <!--  
  12.             1.所有活动都需通过activity标签来注册,且放在application标签中  
  13.             2.android:name:指定注册哪一个活动;.FirstActivity是缩写,因为包名在manifest标签中已经定义了  
  14.             3.android:label:活动标题栏的内容,显示在最顶部  
  15.             4.给主活动指定的label还会成为启动器(Launcher)中应用程序显示的名称  
  16.         -->  
  17.         <activity android:name=".FirstActivity" android:label="This is the firstActivity">  
  18.             <intent-filter>  
  19.                 <!--让活动成为主活动(main入口)就要声明这两句话-->  
  20.                 <action android:name="android.intent.action.MAIN" />  
  21.                 <category android:name="android.intent.category.LAUNCHER" />  
  22.             </intent-filter>  
  23.         </activity>  
  24.     </application>  
  25.   
  26. </manifest>  


2.2.4 隐藏标题栏

[java] view plain copy
  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.         super.onCreate(savedInstanceState);  
  4.         //隐藏标题栏,一定要写在setContentView方法前面  
  5.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  6.         setContentView(R.layout.activity_first);  
  7. }  


注意:
使用AS创建的activity隐藏标题栏时无效,是因为AS默认继承的是AppCompatActivity类,换成Activity类即可。

2.2.5 使用Toast悬浮提示

       Toast是Android系统提供的提示方式,可将信息展示给用户,并在一段时间后消失。
        可给按钮添加点击事件,并提示:
[java] view plain copy
  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     //隐藏标题栏  
  5.     requestWindowFeature(Window.FEATURE_NO_TITLE);  
  6.     setContentView(R.layout.activity_first);  
  7.   
  8.     /** 
  9.      * 1.通过findViewById()来获得界面上的元素,返回View对象,并向下转型 
  10.      * 2.通过实现OnClicklistener接口的onClick()来给按钮添加点击事件 
  11.      */  
  12.     Button btn = (Button) findViewById(R.id.btn_1);  
  13.     btn.setOnClickListener(new View.OnClickListener() {  
  14.         @Override  
  15.         public void onClick(View v) {  
  16.             /** 
  17.              * 别忘了调用.show()方法 
  18.              * param1:Context上下文,由于活动本身就是,所以传入活动对象即可 
  19.              * param2:提示内容 
  20.              * param3:提示显示时长,还有LENGTH_LONG 
  21.              */  
  22.             Toast.makeText(FirstActivity.this"You click the button!", Toast.LENGTH_SHORT).show();  
  23.         }  
  24.     });  
  25. }  

2.2.6 使用menu菜单

(1)在res下新建menu文件夹
(2)在menu下新建一个名为main的菜单文件(在AS中直接new一个Menu resource file)
(3)AS创建之后默认是一个空的menu标签,需要添加菜单项代码:
[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item  
  4.         android:id="@+id/item_add"  
  5.         android:title="Add" />  
  6.     <item  
  7.         android:id="@+id/item_remove"  
  8.         android:title="Remove" />  
  9. </menu>  
(4)在活动中重写onCreateOptionsMenu()使得菜单展示
[java]  view plain  copy
  1. /** 
  2.  * 重写展示菜单的方法 
  3.  * @param menu 
  4.  * @return 
  5.  */  
  6. @Override  
  7. public boolean onCreateOptionsMenu(Menu menu) {  
  8.     /** 
  9.      * 通过此方式给当前活动创建菜单 
  10.      * param1:指定哪个资源文件创建菜单 
  11.      * param2:指定菜单项将添加到哪个菜单中,直接使用方法中传入的参数即可 
  12.      * return:true允许菜单展示,false则不显示 
  13.      */  
  14.     getMenuInflater().inflate(R.menu.main,menu);  
  15.     return true;  
  16. }  
(5)在活动中重写onOptionsItemSelected()响应菜单点击事件
[java]  view plain  copy
  1. /** 
  2.  * 重写响应菜单点击事件的方法 
  3.  * 
  4.  * @param item 
  5.  * @return 
  6.  */  
  7. @Override  
  8. public boolean onOptionsItemSelected(MenuItem item) {  
  9.     //item.getItemId()用来获取选中菜单的id  
  10.     switch (item.getItemId()) {  
  11.         case R.id.item_add:  
  12.             Toast.makeText(FirstActivity.this"You click add menu!", Toast.LENGTH_SHORT).show();  
  13.             break;  
  14.         case R.id.item_remove:  
  15.             Toast.makeText(FirstActivity.this"You click remove menu!", Toast.LENGTH_SHORT).show();  
  16.             break;  
  17.     }  
  18.     return true;  
  19. }  

2.2.7 销毁活动

返回键可以销毁;当然代码也能:finish();即可

2.3 意图(Intent)

2.3.1 概念

        Intent 是 Android 程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent 一般可被用于启动活动、启动服务、以及发送广播等场景。
        Intent的用法大概分为两种:显式意图隐式意图

2.3.2 显式意图

        同样方法创建第二个Activity——SecondActivity,并在FirstActivity中按钮点击事件中编写如下代码:
[java]  view plain  copy
  1. btn.setOnClickListener(new View.OnClickListener() {  
  2.     @Override  
  3.     public void onClick(View v) {  
  4.         /** 
  5.          * param1:为当前活动上下文 
  6.          * param2:要启动的活动 
  7.          */  
  8.         Intent intent =new Intent(FirstActivity.this,SecondActivity.class);  
  9.         startActivity(intent);  
  10.     }  
  11. });  

2.3.3 隐式意图

        指定了一系列更为抽象的 action和 category等信息,然后交由系统去分析这个 Intent,并帮我们找出合适的活动去启动。
         隐式意图需要在activity标签下的intent-filter标签中指定action和category,只有action和category同时匹配的情况下(除去当category配置为默认 android:name="android.intent.category.DEFAULT" 时),该活动才能响应。如:
[html]  view plain  copy
  1. <activity android:name=".SecondActivity" >  
  2.     <intent-filter>  
  3.         <action android:name="com.example.activitytest.ACTION_START" />  
  4.         <category android:name="android.intent.category.DEFAULT" />  
  5.     </intent-filter>  
  6. </activity>  
java代码如下:
[java]  view plain  copy
  1. Intent intent=newIntent("com.example.activitytest.ACTION_START");  
  2. startActivity(intent);  
每个 Intent 中只能指定一个 action,但却能指定多个 category。
[java]  view plain  copy
  1. intent.addCategory("...");  

2.3.4 隐式意图更多用法

隐式意图不但能打开自己应用的activity,还能打开系统的activity,如浏览器、拨号等等。
[java]  view plain  copy
  1. @Override  
  2. public void onClick(View v) {  
  3.     /** 
  4.      * 1.Intent.ACTION_VIEW 这是系统内置动作,其常量值为android.intent.action.VIEW 
  5.      * 2.通过Uri.parse()方法将网址解析为Uri对象 
  6.      * 3.调用setData将Uri对象传递。 
  7.      */  
  8.     Intent intent = new Intent(Intent.ACTION_VIEW);  
  9.     intent.setData(Uri.parse("http://www.baidu.com"));  
  10.     startActivity(intent);  
  11.   
  12.     //打电话  
  13.     //Intent intent=new Intent(Intent.ACTION_DIAL);  
  14.     //intent.setData(Uri.parse("tel:10086"));  
  15.     //startActivity(intent);  
  16. }  

2.3.5 向下一个Activity传递数据

(1)第一个activity:
[java]  view plain  copy
  1. Intent intent = new Intent(FirstActivity.this, SecondActivity.class);  
  2. //使用putExtra()方法传递数据  
  3. intent.putExtra("data""这是我传递的数据");  
  4. startActivity(intent);  
(2)第二个activity:
[java]  view plain  copy
  1. //通过getIntent()方法获取启动当前activity的意图对象  
  2. Intent intent = getIntent();  
  3. //什么类型的数据就get类型Extra("");  
  4. String data = intent.getStringExtra("data");  
  5. Log.d("SecondActivity", data);  

2.3.6 返回数据给上一个Activity

Activity中提供了一个startActivityForResult()方法,此方法期望在活动销毁后能够返还一个数据给上一个活动。
(1)在第一个activity中如下编写:
[java]  view plain  copy
  1. Intent intent = new Intent(FirstActivity.this, SecondActivity.class);  
  2. intent.putExtra("data""这是我传递的数据");  
  3. //startActivity(intent);  
  4. /** 
  5.  * param1:仍然是意图对象 
  6.  * param2:请求码,用于在之后的回调中判断数据来源,只要是唯一值就可以了,这里传入1 
  7.  */  
  8. startActivityForResult(intent, 1);  
(2)第二个activity中重写onBackPressed()方法,此方法表示用户点击了返回键:
[java]  view plain  copy
  1. @Override  
  2. public void onBackPressed() {  
  3.     //声明意图,但此处的意图仅仅是为了传递数据,并不是要启动Activity  
  4.     Intent intent=new Intent();  
  5.     intent.putExtra("data_back","这是返回的数据~~~");  
  6.     /** 
  7.      * 通过setResult方法来返回数据,非常重要 
  8.      * param1:返回处理结果,常用的是RESULT_OK,RESULT_CANCELED 
  9.      * param2:意图对象,传递数据 
  10.      */  
  11.     setResult(RESULT_OK,intent);  
  12.     //销毁活动  
  13.     finish();  
  14. }  
(3)在第一个activity中重写回调方法onActivityResult()
[java]  view plain  copy
  1. /** 
  2.  * 第二个活动处理完成后返回第一个活动的回调函数 
  3.  * @param requestCode 启动第二个活动时传入的请求码,即1 
  4.  * @param resultCode 第二个活动返回的处理结果 
  5.  * @param intent 携带着返回数据的intent 
  6.  */  
  7. @Override  
  8. protected void onActivityResult(int requestCode, int resultCode, Intent intent) {  
  9.     switch (requestCode){  
  10.         // 判断请求码是不是我们所传递的  
  11.         case 1:  
  12.             if (resultCode==RESULT_OK){  
  13.                 String dataBack= intent.getStringExtra("data_back");  
  14.                 Toast.makeText(FirstActivity.this"返回:"+dataBack, Toast.LENGTH_SHORT).show();  
  15.             }  
  16.             break;  
  17.         default:  
  18.     }  
  19. }  

2.4 生命周期

2.4.1 返回栈

        Android中的活动是层叠的,每启动一个活动,就会覆盖在原来的活动上面,然后点击Back键就会销毁最上面的。
        Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的集合,这个栈被称作返回栈(Back Stack)

2.4.2 状态

  • 运行:当活动处于返回栈的栈顶时,则这个活动是运行状态
  • 暂停:当一个活动不处于栈顶、但仍然可见时,这个活动处于暂停状态,
  • 停止:当一个活动不在处于栈顶时,而且完全不可见时,则进入了停止状态。当其他地方需要内存时,停止状态的活动极有可能被回收
  • 销毁:当一个活动从返回栈中移除后就变成了销毁状态。

2.4.3 生存期

  • onCreate():活动初次创建时调用,做初始化工作
  • onStart():对用户即将可见的时候调用
  • onResume():将要与用户交互的时候调用(此时活动一定处于栈顶,且运行状态)
  • onPause():准备去启动或者恢复另一个活动时调用
  • onStop():完全不可见时调用
  • onDestroy():被销毁之前调用,调用后则变为销毁状态
  • onRestart():活动由停止状态变为运行状态之前调用(重新启动)

三种生存期:
(1)完整生存期:onCreate()-->onDestroy()的过程
(2)可见生存期:onStart()-->onStop()的过程
(3)前台生存期:onResume()-->onPause()

2.4.4 活动被回收如何处理

        活动在停止状态是容易被系统回收的(比如系统内存不足情况下),如何解决活动被回收时临时数据得不到保存的问题?
        Activity 中提供了一个onSaveInstanceState()回调方法,这个方法会保证一定在活动被回收之前调用。
[java]  view plain  copy
  1. /** 
  2.  * Bundle类型的参数提供了一系列的方法用于保存数据 
  3.  * @param outState 
  4.  */  
  5. @Override  
  6. protected void onSaveInstanceState(Bundle outState) {  
  7.     super.onSaveInstanceState(outState);  
  8.     /** 
  9.      * put系列方法,依次类推,如putInt.... 
  10.      * param1:数据的键值 
  11.      * param2:数据 
  12.      */  
  13.     outState.putString("data_key","something you want to save.");  
  14. }  
        保存完成后可以在onCreate方法里面获取数据(因为活动被回收之后再运行此活动就会重新创建),onCreate方法也有一个Bundle类型的参数savedInstanceState:
[java]  view plain  copy
  1. if(savedInstanceState!=null){  
  2.     String data=savedInstanceState.getString("data_key");  
  3.     //其他操作....  
  4. }  
还可以结合intent传递数据(把数据放在Bundle中,再把Bundle放到Intent中)。

2.5 启动模式

  • standard
活动默认的启动模式,在此模式下,每当启动一个新的活动,他就会在返回栈中入栈,并处于顶部,系统不会在乎这个活动在返回栈中是否已存在,每次启动都会创建一个活动的实例。
  • singleTop
启动活动时如果发现返回栈栈顶已经是该活动(注意是栈顶),则认为可直接使用它,不会再创建活动的实例。但不是在栈顶时,则还会创建实例。
  • singleTask
在整个应用程序的上下文中,只存在一个该活动的实例。当启动活动时,首先检查返回栈中是否已存在,若存在,则把该活动之上的活动统统移除出栈,如果没有发现就会创建一个新的实例。
  • singleInstance
该模式下的活动会启用一个新的返回栈来管理,这样做的意义就是可以和其他程序之间共享这个活动的实例(用以上三种模式的话,每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈入栈时必然是创建了新的实例,做不到共享的效果)。

2.6 实践技巧

2.6.1 识别当前是在哪一个活动

        新建一个BaseActivity继承Activity,然后重写onCreate()方法,让其他的Activity类继承BaseActivity类,在BaseActivity类的onCreate方法中打印:
[java]  view plain  copy
  1. Log.d("BaseActivity", getClass().getSimpleName());  

2.6.2 随时退出应用

(1)新建一个活动管理类:
[java]  view plain  copy
  1. package com.jastar.activitylifecycletest;  
  2.   
  3. import android.app.Activity;  
  4.   
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. /** 
  9.  * Created by admin on 2016/9/29. 
  10.  */  
  11. public class ActivityCollector {  
  12.   
  13.     //通过list来暂存活动  
  14.     public static List<Activity> activities = new ArrayList<Activity>();  
  15.   
  16.     public static void addActivity(Activity activity) {  
  17.         activities.add(activity);  
  18.     }  
  19.   
  20.     public static void removeActivity(Activity activity) {  
  21.         activities.remove(activity);  
  22.     }  
  23.   
  24.     public static void finishAll() {  
  25.         for (Activity activity : activities) {  
  26.             if (!activity.isFinishing()) {  
  27.                 activity.finish();  
  28.             }  
  29.         }  
  30.     }  
  31. }  
(2)在BaseActivity中重写onCreate()和onDestroy()方法实现向list中添加和移除activity
[java]  view plain  copy
  1. ActivityCollector.addActivity(this);  
  2. ActivityCollector.removeActivity(this);  
(3)在想退出应用的地方调用ActivityCollector.finishAll()即可。

2.6.3 启动活动的最佳写法

(1)常规的思路:
        在FirstActivity中创建意图,存放数据,然后启动SecondActivity——合理且完全没问题,但是不知道需要传递什么数据,需要哪些参数。
(2)更好的思路:
        在SecondActivity中添加下面的方法,然后在FirstActivity中调用即可——传递哪些数据参数一目了然,一行代码即可启动活动。
[java]  view plain  copy
  1. public static void actionStart(Context context, String param1, String param2) {  
  2.     Intent intent = new Intent(context, SecondActivity.class);  
  3.     intent.putExtra("param1", param1);  
  4.     intent.putExtra("param2", param2);  
  5.     context.startActivity(intent);  
  6. }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值