美文网首页android
Android_Activity

Android_Activity

作者: 738bc070cd74 | 来源:发表于2015-07-09 13:46 被阅读196次

    生命周期

    官网上的生命周期图:

    activity_lifecycle.png
    • onCreate: Activity正在创建,生命周期的第一个方法。在此方法中做一些初始化工作(setContentView加载界面布局,加载基本数据)
    • onStart: Activity 正在启动,已经可见,但在后台(没有获得焦点)
    • onResume: Activity获得焦点出现在前台可以交互
    • onPause: Activity 正在停止,可做一些数据存储,停止动画...
    • onStop: Activity 停止,不可见
    • onDestory: Activity 销毁,进行资源回收

    基本函数

    public void onCreate(Bundle savedInstanceState);
    public void onStart();
    public void onRestart();
    public void onActivityResult(int requestCode, int resultCode, Intent data);
    public void onResume();
    public void onPause();
    public void onStop();
    public void onDestroy();
    public void attach(Activity proxyActivity, DLPluginPackage pluginPackage);
    public void onSaveInstanceState(Bundle outState);
    public void onNewIntent(Intent intent);
    public void onRestoreInstanceState(Bundle savedInstanceState);
    public boolean onTouchEvent(MotionEvent event);
    public boolean onKeyUp(int keyCode, KeyEvent event);
    public void onWindowAttributesChanged(LayoutParams params);
    public void onWindowFocusChanged(boolean hasFocus);
    public void onBackPressed();
    public boolean onCreateOptionsMenu(Menu menu);
    public boolean onOptionsItemSelected(MenuItem item);
    
    • onRestart:Activity 正在重现启动,是当前Activity从不可见到可见状态会触发
    • onActivityResult: 在Activity中得到新打开Activity关闭后返回的数据

    特殊情况下触发(横竖屏切换,资源不足被杀)

    • onSaveInstanceState:Activity被销毁,调用此方法保存当前状态,在onStop之前调用
    • onRestoreInstanceState:Activity 被重启调用,通过Bundle传递保存的数据,在onStart 之后调用
    • onNewIntent
    • onTouchEvent 触摸屏幕时调用,可以获取手势的位置
    • onKeyUp 键盘事件,点击来手机按键
    • onWindowAttributesChanged
    • onWindowFocusChanged
    • onBackPressed 返回键点击
    • onCreateOptionsMenu 加载菜单布局
    • onOptionsItemSelected 响应菜单选项

    对话框模式

    <activity
            android:name=".TAccountActivity"
            android:theme="@android:style/Theme.Translucent" 
            android:configChanges="fontScale|orientation|keyboardHidden|locale|navigation|screenSize|uiMode"
            android:screenOrientation="portrait"
            />
    

    布局文件设置在父布局的中间,动态添加一个fragment

     <FrameLayout
        android:id="@+id/account_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
         />
    

    启动模式

    • Standared(默认):standard是默认的启动模式,即如果不指定launchMode属性,则自动就会使用这种启动模式。这种启动模式表示每次启动该Activity时系统都会为创建一个新的实例,并且总会把它放入到当前的任务当中。声明成这种启动模式的Activity可以被实例化多次,一个任务当中也可以包含多个这种Activity的实例。

    • SingleTop:这种启动模式表示,如果要启动的这个Activity在当前任务中已经存在了,并且还处于栈顶的位置,那么系统就不会再去创建一个该Activity的实例,而是调用栈顶Activity的onNewIntent()方法。声明成这种启动模式的Activity也可以被实例化多次,一个任务当中也可以包含多个这种Activity的实例。
      举个例子来讲,一个任务的返回栈中有A、B、C、D四个Activity,其中A在最底端,D在最顶端。这个时候如果我们要求再启动一次D,并且D的启动模式是"standard",那么系统就会再创建一个D的实例放入到返回栈中,此时栈内元素为:A-B-C-D-D。而如果D的启动模式是"singleTop"的话,由于D已经是在栈顶了,那么系统就不会再创建一个D的实例,而是直接调用D Activity的onNewIntent()方法,此时栈内元素仍然为:A-B-C-D。

    • SingleTask:这种启动模式表示,系统会创建一个新的任务,并将启动的Activity放入这个新任务的栈底位置。但是,如果现有任务当中已经存在一个该Activity的实例了,那么系统就不会再创建一次它的实例,而是会直接调用它的onNewIntent()方法。声明成这种启动模式的Activity,在同一个任务当中只会存在一个实例。注意这里我们所说的启动Activity,都指的是启动其它应用程序中的Activity,因为"singleTask"模式在默认情况下只有启动其它程序的Activity才会创建一个新的任务,启动自己程序中的Activity还是会使用相同的任务

    • SingleInstance:这种启动模式和"singleTask"有点相似,只不过系统不会向声明成"singleInstance"的Activity所在的任务当中再添加其它Activity。也就是说,这种Activity所在的任务中始终只会有一个Activity,通过这个Activity再打开的其它Activity也会被放入到别的任务当中。
      再举一个例子,Android系统内置的浏览器程序声明自己浏览网页的Activity始终应该在一个独立的任务当中打开,也就是通过在<activity>元素中设置"singleTask"启动模式来实现的。这意味着,当你的程序准备去打开Android内置浏览器的时候,新打开的Activity并不会放入到你当前的任务中,而是会启动一个新的任务。而如果浏览器程序在后台已经存在一个任务了,则会把这个任务切换到前台。
      其实不管是Activity在一个新任务当中启动,还是在当前任务中启动,返回键永远都会把我们带回到之前的一个Activity中的。但是有一种情况是比较特殊的,就是如果Activity指定了启动模式是"singleTask",并且启动的是另外一个应用程序中的Activity,这个时候当发现该Activity正好处于一个后台任务当中的话,就会直接将这整个后台任务一起切换到前台

    启动方式

    显式

    需要知道SecondActivity的存在

    Intent intent=new Intent(MainActivity.this, SecondActivity.class); 
    //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    startActivity(intent);
    

    使用Intent flags

    除了使用manifest文件之外,你也可以在调用startActivity()方法的时候,为Intent加入一个flag来改变Activity与任务的关联方式

    • FLAG_ACTIVITY_NEW_TASK
      设置了这个flag,新启动Activity就会被放置到一个新的任务当中(与"singleTask"有点类似,但不完全一样),当然这里讨论的仍然还是启动其它程序中的Activity。这个flag的作用通常是模拟一种Launcher的行为,即列出一推可以启动的东西,但启动的每一个Activity都是在运行在自己独立的任务当中的。

    • FLAG_ACTIVITY_SINGLE_TOP
      设置了这个flag,如果要启动的Activity在当前任务中已经存在了,并且还处于栈顶的位置,那么就不会再次创建这个Activity的实例,而是直接调用它的onNewIntent()方法。这种flag和在launchMode中指定"singleTop"模式所实现的效果是一样的。

    • FLAG_ACTIVITY_CLEAR_TOP
      设置了这个flag,如果要启动的Activity在当前任务中已经存在了,就不会再次创建这个Activity的实例,而是会把这个Activity之上的所有Activity全部关闭掉。比如说,一个任务当中有A、B、C、D四个Activity,然后D调用了startActivity()方法来启动B,并将flag指定成FLAG_ACTIVITY_CLEAR_TOP,那么此时C和D就会被关闭掉,现在返回栈中就只剩下A和B了。
      那么此时Activity B会接收到这个启动它的Intent,你可以决定是让Activity B调用onNewIntent()方法(不会创建新的实例),还是将Activity B销毁掉并重新创建实例。如果Activity B没有在manifest中指定任何启动模式(也就是"standard"模式),并且Intent中也没有加入一个FLAG_ACTIVITY_SINGLE_TOP flag,那么此时Activity B就会销毁掉,然后重新创建实例。而如果Activity B在manifest中指定了任何一种启动模式,或者是在Intent中加入了一个FLAG_ACTIVITY_SINGLE_TOP flag,那么就会调用Activity B的onNewIntent()方法。
      FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK结合在一起使用也会有比较好的效果,比如可以将一个后台运行的任务切换到前台,并把目标Activity之上的其它Activity全部关闭掉。这个功能在某些情况下非常有用,比如说从通知栏启动Activity的时候。

    • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS Activity不会出现在历史activity的列表中,等价于 xml 中配置
      android:excludeFromRecents="treu"

    隐式

    隐式启动不同之处在于我们并不需要像Intent(MainActivity.this, SecondActivity.class)这样传参数然后再Start另一个Activity.我们需要在intent添加过滤器intentfilter。

    <activity
        android:name="com.example.android.tst.SecondActivity"
        android:label="@string/title_activity_main" > 
        <intent-filter> 
            <action android:name="com.example.android.tst.SecondActivity"/> 
            <category android:name="android.intent.category.DEFAULT" /> 
        </intent-filter> 
    </activity>
    
    Intent intent=new Intent("com.example.android.tst.SecondActivity"); 
    startActivity(intent);
    
    • action 匹配,字符串匹配(系统内置,自定义),区分大小写。一个过滤规则中可以有多个action,只要任何一个匹配成功即可
    • category 匹配,也是一个字符串,(系统内置,自定义),每一个都需要匹配成功,系统会自动加上
      <category android:name="android.intent.category.DEFAULT" /> 的匹配
    • data 匹配, scheme, host, port, path, pathPrefix, pathPattern 是用来匹配 Intent 中的 Data Uri 的。具体规则如下: scheme://host:port/path or pathPrefix or pathPattern

    setType 调用后设置 mimeType,然后将 data 置为 null;
    setData 调用后设置 data,然后将 mimeType 置为 null;
    setDataAndType 调用后才会同时设置 data 与 mimeType。

    • 示例,短信中包含一个连接,可以直接打开应用

        <intent-filter>
                <action android:name="android.intent.action.VIEW" />
      
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
      
                <data
                    android:host="www.aaa.com"
                    android:pathPrefix="/bbb"
                    android:scheme="http" />
                <data
                    android:host="www.aaa.com"
                    android:pathPrefix="/ccc"
                    android:scheme="http" />
            </intent-filter>
      

    清空返回栈

    如果用户将任务切换到后台之后过了很长一段时间,系统会将这个任务中除了最底层的那个Activity之外的其它所有Activity全部清除掉。当用户重新回到这个任务的时候,最底层的那个Activity将得到恢复。这个是系统默认的行为,因为既然过了这么长的一段时间,用户很有可能早就忘记了当时正在做什么,那么重新回到这个任务的时候,基本上应该是要去做点新的事情了。
    当然,既然说是默认的行为,那就说明我们肯定是有办法来改变的,在<activity>元素中设置以下几种属性就可以改变系统这一默认行为:

    • alwaysRetainTaskState
      如果将最底层的那个Activity的这个属性设置为true,那么上面所描述的默认行为就将不会发生,任务中所有的Activity即使过了很长一段时间之后仍然会被继续保留。
    • clearTaskOnLaunch
      如果将最底层的那个Activity的这个属性设置为true,那么只要用户离开了当前任务,再次返回的时候就会将最底层Activity之上的所有其它Activity全部清除掉。简单来讲,就是一种和alwaysRetainTaskState完全相反的工作模式,它保证每次返回任务的时候都会是一种初始化状态,即使用户仅仅离开了很短的一段时间。
    • finishOnTaskLaunch
      这个属性和clearTaskOnLaunch是比较类似的,不过它不是作用于整个任务上的,而是作用于单个Activity上。如果某个Activity将这个属性设置成true,那么用户一旦离开了当前任务,再次返回时这个Activity就会被清除掉。

    启动流程

    启动流程.png

    相关文章

      网友评论

        本文标题:Android_Activity

        本文链接:https://www.haomeiwen.com/subject/irxuqttx.html