Andorid——Activity总结

一、什么是activity

Activity是Android组件中最基本也是最为常见用的四大组件之一。
Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务。
Activity中所有操作都与用户密切相关,是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件。
在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。

二、activity生命周期

  


由图可知:

  在一个Activity正常启动过程中,这些方法调用的顺序是onCreate -> onStart -> onResume;在Activity被kill掉的时候方法顺序是onPause -> onStop -> onDestroy,此为一个完整的Lifecycle。那么对于中断处理(比如电话来了),则是onPause -> onStop,恢复时onStart -> onResume;如果当前应用程序的是一个Theme为Translucent(半透明) 或者Dialog 的Activity那么中断就是onPause ,恢复的时候onResume。

  那么对于”Other app need memory”,就是我们手机在运行一个应用程序的时候,有可能打进来电话发进来短信,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能,另外系统也不允许你占用太多资源,至少要保证一些功能(比如电话),所以资源不足的时候也就有可能被kill掉。

方法在系统中的作用及我们应该做什么:

  onCreate:在这里创建界面,做一些数据的初始化工作;

  onStart: 到这一步变成“用户可见不可交互”的状态;

  onResume:变成和用户可交互的,(在Activity栈系统通过栈的方式管理这些Activity,即当前Activity在栈的最上端,运行完弹出栈,则回到上一个Activity);

  onPause:到这一步是可见但不可交互的,系统会停止动画等消耗CPU的事情。从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候你的程序的优先级降          低,有可能被系统收回。在这里保存的数据,应该在onResume里读出来。

  onStop:变得不可见 ,被下一个activity覆盖了

  onDestroy:这是Activity被kill前最后一个被调用方法了,可能是其他类调用finish方法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判断它,如果你有              一个Progress Dialog在线程中运行,请在onDestroy里把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛异常。

onPause,onstop, onDestroy,三种状态下 activity都有可能被系统kill 掉。

三、Activity四种状态

Running状态:一个新的Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
Paused状态:当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。
Stopped状态:当Activity不可见时,Activity处于Stopped状态。当Activity处于此状态时,一定要保存当前数据和当前的UI状态,否则一旦Activity退出或关闭时,当前的数据和UI状态就丢失了。
Killed状态:Activity被杀掉以后或者被启动以前,处于Killed状态。这是Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。

4种状态中,Running状态和Paused状态是可见的,Stopped状态和Killed状态时不可见的。

四、Activity之间的通信

  在 Android 中,不同的 Activity 实例可能运行在一个进程中,也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在 Activity 之间传递消息。Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。

  Intent负责对操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。

  在应用中,我们可以以两种形式来使用Intent:

  直接Intent:指定了component属性的Intent(调用setComponent(ComponentName)或者setClass(Context, Class)来指定)。通过指定具体的组件类,通知应用启动对应的组件。

  间接Intent:没有指定comonent属性的Intent。这些Intent需要包含足够的信息,这样系统才能根据这些信息,在在所有的可用组件中,确定满足此Intent的组件。
      对于直接Intent,Android不需要去做解析,因为目标组件已经很明确。

  Android需要解析的是那些间接Intent,通过解析,将 Intent映射给可以处理此Intent的Activity、IntentReceiver或Service。Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。

五、Activity 的 Intent Filter

  Intent Filter 描述了一个组件愿意接收什么样的 Intent 对象,Android 将其抽象为 android.content.IntentFilter 类。在 Android 的 AndroidManifest.xml 配置文件中可以通过 <intent-filter >节点为一个 Activity 指定其 Intent Filter,以便告诉系统该 Activity 可以响应什么类型的 Intent。

  当使用 startActivity(intent) 来启动另外一个 Activity 时,如果直接指定 intent 对象的 Component 属性,那么 Activity Manager 将试图启动其 Component 属性指定的 Activity。否则 Android 将通过 Intent 的其它属性从安装在系统中的所有 Activity 中查找与之最匹配的一个启动,如果没有找到合适的 Activity,应用程序会得到一个系统抛出的异常。这个匹配的过程如下:

六、Activity的栈式管理

  Android针对Activity的管理使用的是栈,就是说某一个时刻只有一个Activity处在栈顶,当这个Activity被销毁后,下面的Activity才有可能浮到栈顶,或者有一个新的Activity被创建出来,则旧的Activity就被压栈沉下去了。Activity是Android程序的表现层。程序的每一个显示屏幕就是一个Activity。正在运行的Activity处在栈的最顶端,它是运行状态的。

                                       

当在程序中调用 Activity.finish()方法时,结果和用户按下 BACK 键一样:它告诉 Activity Manager该Activity实例可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity ,把原 Activity 压入到栈的第二层,从 Running 状态转到 Paused 状态。

七、Activity的加载模式

standard、singleTop、singleTask、singleInstance(其中前两个是一组、后两个是一组),默认为standard 

standard:就是intent将发送给新的实例,所以每次跳转都会生成新的activity。

singleTop:也是发送新的实例,但不同standard的一点是,在请求的Activity正好位于栈顶时(配置成singleTop的Activity),不会构造新的实例

singleTask:singleTask方式和singleTop方式也基本相同,当要重新启动一个ActivityA的时候,并不管ActivityA在不在栈顶,只有栈中有Activity,将不会再新建一个AcvitityA。并且同时,栈中所有在之前的那个Activity上面的Activity都会被finish掉。

singleInstance:

首先说明一下task这个概念,Task可以认为是一个栈,可放入多个Activity。比如启动一个应用,那么Android就创建了一个Task,然后启动这个应用的入口Activity,那在它的界面上调用其他的Activity也只是在这个task里面。那如果在多个task中共享一个Activity的话怎么办呢。举个例来说,如果开启一个导游服务类的应用程序,里面有个Activity是开启GOOGLE地图的,当按下home键退回到主菜单又启动GOOGLE地图的应用时,显示的就是刚才的地图,实际上是同一个Activity,实际上这就引入了singleInstance。singleInstance模式就是将该Activity单独放入一个栈中,这样这个栈中只有这一个Activity,不同应用的intent都由这个Activity接收和展示,这样就做到了共享。当然前提是这些应用都没有被销毁,所以刚才是按下的HOME键,如果按下了返回键,则无效。

八、Activity的跳转

Activity跳转,无返回结果
   这是最简单的Activity跳转方式。从一个Activity启动另一个Activity,直接startActivity(new Intent(当前Activity.this, 下一Activity.class))。
Activity跳转,返回数据/结果
   需要返回数据或结果的,则使用startActivityForResult (Intent intent, int requestCode),requestCode的值是自定义的,用于识别跳转的目标Activity。跳转的目标Activity所要做的就是返回数据/结果,setResult(int resultCode)只返回结果不带数据,或者setResult(int resultCode, Intent data)两者都返回!而接收返回的数据/结果的处理函数是onActivityResult(int requestCode, int resultCode, Intent data),这里的requestCode就是startActivityForResult的requestCode,resultCode就是setResult里面的resultCode,返回的数据在data里面。

九、Activity如何设置全屏?如何设置成窗口样式?

Activity设置成全屏有2中方式:
1、在AndroidManifest.xml里面添加一句:
Android:theme="@android:style/Theme.NoTitleBar.Fullscreen"  
2、在activity的onCreate里面setContentView之前添加一下两行代码:

无标题栏:requestWindowFeature(Window.FEATURE_NO_TITLE);

全屏:getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                                                                     WindowManager.LayoutParams.FLAG_FULLSCREEN);

使用代码可以动态使该Activity进行全屏,如可实现屏幕双击后进行全屏等~

Activity设置成窗口样式:

1.在AndroidManifest.xml文件中设置当前需要改变成窗口样式的Activity的属性,即

[html]  view plain  copy
  1. android:theme="@android:style/Theme.Dialog"  
或者

[html]  view plain  copy
  1. android:theme="@android:style/Theme.Holo.Dialog"  
2.在styles.xml文件中自定义一个主题样式,改主题样式必须继承Dialog的样式。然后在 AndroidManifest.xml文件中引用你自定义的主题即可。

[html]  view plain  copy
  1. <style name="Theme.MyDialog" parent="android:style/Theme.Dialog">  
  2.         <item name="android:windowBackground">@drawable/my_dialog</item>  
  3.     </style>  
在drawable中新建 my_dialog.xml文件,内容如下:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <solid android:color="#ffffff" />  
  4.     <stroke  
  5.         android:width="3dp"  
  6.         android:color="@android:color/holo_blue_light" />  
  7.     <corners android:radius="3dp" />  
  8.     <padding  
  9.         android:left="10dp"  
  10.         android:top="10dp"  
  11.         android:right="10dp"  
  12.         android:bottom="10dp" />  
  13. </shape>  
AndroidManifest.xml文件中设置当前需要改变成窗口样式的Activity的属性,即

[html]  view plain  copy
  1. android:theme="@style/Theme.MyDialog"

十、怎么关闭所有Activity?

有时我们可能会打开了很多个Activity,突然来个这样的需求,在某个页面可以关掉 所有的Activity并退出程序!好吧,下面提供一个关闭所有Activity的方法, 就是用一个list集合来存储所有Activity!

具体代码如下:

<span style="font-size:14px;">public class ActivityCollector {  
    public static LinkedList<Activity> activities = new LinkedList<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();  
            }  
        }  
    }  
}  </span>

<span style="font-size:14px;">package com.tarena.exit.model;  
import java.util.LinkedList;  
import android.app.Activity;  
import android.os.Bundle;  
  
public class BaseActivity extends Activity {  
    public static LinkedList<Activity> allActivitys = new LinkedList<Activity>();  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        allActivitys.add(this);  
    }  
    @Override  
    protected void onDestroy() {  
        super.onDestroy();  
        allActivitys.remove(this);  
    }  
    public static void finishAll(){  
        for (Activity activity : allActivitys) {  
            activity.finish();  
        }  
        allActivitys.clear();  
         //这个主要是用来关闭进程的, 光把所有activity finish的话,进程是不会关闭的  
        System.exit(0);    
//      android.os.Process.killProcess(android.os.Process.myPid());   
    }  
}  </span>




完全退出App的方法

上面说的是关闭所有Activity的,但是有些时候我们可能想杀死整个App,连后台任务都杀死 杀得一干二净的话,可以使用搭配着下述代码使用:

实现代码:

<span style="font-size:14px;">/** 
 * 退出应用程序 
 */  
public void AppExit(Context context) {  
    try {  
        ActivityCollector.finishAll();  
        ActivityManager activityMgr = (ActivityManager) context  
                .getSystemService(Context.ACTIVITY_SERVICE);  
        activityMgr.killBackgroundProcesses(context.getPackageName());  
        System.exit(0);  
    } catch (Exception ignored) {}  
}  </span>


6.双击退出程序的两种方法:

1)定义一个变量,来标识是否退出

// 定义一个变量,来标识是否退出
private static boolean isExit = false;
Handler mHandler = new Handler() {
	@Override
	public void handleMessage(Message msg) {
		super.handleMessage(msg);
		isExit = false;
	}
};

public boolean onKeyDown(int keyCode, KeyEvent event) {
	if (keyCode == KeyEvent.KEYCODE_BACK) {
		if (!isExit) {
			isExit = true;
			Toast.makeText(getApplicationContext(), "再按一次退出程序",
					Toast.LENGTH_SHORT).show();
			// 利用handler延迟发送更改状态信息
			mHandler.sendEmptyMessageDelayed(0, 2000);
		} else {
			exit(this);
		}
		return false;
	}
return super.onKeyDown(keyCode, event);}



2)保存点击时间:

//保存点击的时间
private long exitTime = 0;
public boolean onKeyDown(int keyCode, KeyEvent event) {
	if (keyCode == KeyEvent.KEYCODE_BACK) {
		if ((System.currentTimeMillis() - exitTime) > 2000) {
			Toast.makeText(getApplicationContext(), "再按一次退出程序",
					Toast.LENGTH_SHORT).show();
			exitTime = System.currentTimeMillis();
		} else {
	                    exit();
	                  }
		return false;
	}
		return super.onKeyDown(keyCode, event);
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中,可以通过 startActivityForResult() 方法启动一个 Activity 并期望该 Activity 返回结果。当被启动的 Activity 结束时,它会返回一个结果给调用它的 Activity。可以在 onActivityResult() 方法中获取返回的结果。 如果你有多个 Activity 都需要返回结果,例如 A Activity 启动 B Activity,B Activity 再启动 C Activity,那么在 C Activity 返回结果后,数据需要经过 B Activity 再传递给 A Activity。 在这种情况下,可以在 startActivityForResult() 方法中传递一个唯一的请求码,在 onActivityResult() 方法中根据请求码来区分不同的 Activity 返回的数据。可以在 setResult() 方法中设置返回的结果码和数据,以便在 onActivityResult() 方法中获取它们。 下面是一个简单的示例代码: 在 A Activity 中启动 B Activity: ``` Intent intent = new Intent(this, BActivity.class); startActivityForResult(intent, 1); ``` 在 B Activity 中启动 C Activity: ``` Intent intent = new Intent(this, CActivity.class); startActivityForResult(intent, 2); ``` 在 C Activity 中返回数据给 B Activity: ``` Intent intent = new Intent(); intent.putExtra("data", "Hello, world!"); setResult(RESULT_OK, intent); finish(); ``` 在 B Activity 中获取返回的数据: ``` @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 2 && resultCode == RESULT_OK) { String result = data.getStringExtra("data"); // 处理返回的数据 } } ``` 在 A Activity 中获取返回的数据: ``` @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1 && resultCode == RESULT_OK) { String result = data.getStringExtra("data"); // 处理返回的数据 } } ``` 需要注意的是,如果在 C Activity 中调用了 finish() 方法,那么在 B Activity 中的 onActivityResult() 方法中就无法再获取到返回的数据了,因为 B Activity 也已经被销毁了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值