《第一行代码》——Intent,数据传递,活动的生命周期

整理自《第一行代码》一二两章

安卓基础知识

启动程序

<activity android:name=".MainActivity">
      <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>

.MainActivity 为开始执行的类文件。这段代码对 MainActivity 活动进行注册,表示其为主活动,在手机上点击应用图标,首先启动的就是此活动。

apply plugin: 'com.android.application'
//插件,application表示是应用模块,library表示是库
android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"
    defaultConfig {
        applicationId "com.example.finaltop"	//指定项目的包名
        minSdkVersion 14					  //项目兼容的最低版本
        targetSdkVersion 29					  //已检测过可运行的版本
        versionCode 1
        versionName "1.0"						//项目版本号和项目版本名
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {			//debug指定生成测试版安装文件的配置 release指定生成正式版安装文件的配置
        release {
            minifyEnabled false			//是否对项目的代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'			//混淆时使用的规则文件
        }
    }
}

Intent(意图)

显示创建Intent

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

隐式创建Intent

当前活动可以相应 com.example.activitytest.ACTION_START这个action,<category>标签包含了附加信息,更精确地指明了当前的活动能够响应的Intent中还可能带有的category。只有两个标签中的内容能够同时匹配上Intent中指定的action和category,该活动才能响应该intent。

<activity android:name=".SecondActivity">
      <intent-filter>
            <action android:name="com.example.activitytest.ACTION_START" />
            <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
</activity>
Intent intent = new Intent("com.example.activitytest.ACTION_START");
//想要启动一种能响应ACTION_START的活动,DEFAULT为默认的category
startActivity(intent);
intent.addCategory("com.example.activitytest.MY_CATEGORY");
//可以通过此函数增加category但是运行会报错,intent可以指定多个category

首先指定了intent的action是ACTION_VIEW,这是安卓系统内置的动作,常量值为 android.intent.action.VIEW 。然后通过 Uri.parse("http://www.baidu.com") 方法将网址字符串解析成Uri对象,再调用 setData() 方法将此对象传递过去。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);

可以配置Data标签,精确指定当前活动能够响应的数据类型。只有标签内指定内容完全一致才可以响应该intent。

android:scheme					//指定数据协议部分
android:host					//指定主机部分
android:port					//指定端口部分
android:path					//指定主机名和端口之后的部分
android:mimeType				//指定可以处理的数据类型,允许使用通配符的方式进行指定
//如下例所示只响应协议为http的活动
<data android:scheme="http" />		

传递数据(前——>后 / 后——>前)

String data = "hello world!";
Intent intent = new Intent(MainActivity.this,ScondActivity.class);
intent.putExtra("extra_data",data);
startActivity(intent);
//将数据传递给下一个intent

Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
//下一个intent进行接收

/*******************************************************************/
Intent intent = new Intent(MainActivity.this,ScondActivity.class);
startActivityForResult(intent,1);//请求码传入唯一值即可
protected void onActivityResult(int requestCode,int resultCode,Intent data){
    switch(requestCode){//启动活动时传入的请求码
        case 1:
            if(resultCode == RESULT_OK){
                String returnedData = data.getStringExtra("data_return");//接收数据
                Log.d("FirstActivity",returnedData);
            }break;
            default;
    }
}


//重写onBackPressed() 用户按下back键也可返回信息
public void onBackPressed(){
    Intent intent = new Intent();
    intent.putExtra("data_return","Hello FirstActivity");
    setResult(RESULT_OK,intent);
	finish();
}

Intent intent = new Intent();
intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK,intent);
finish();
//将带有返回数据的意图传递回去
/*************************使用bundle***********************************/
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    String tempData = "something";
    outState.putString("data_key",tempData);
}

protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.id.activity_main);
    if(savedInstanceState!=null){
        String tempData = savedInstanceState.getString("data_key");
        Log.d(TAG,tempData);
    }
}

活动的生命周期

活动状态:运行状态、暂停状态、停止状态、销毁状态

活动的生存期

完整生存期:活动在onCreate()和onDestroy()之间经历的就是完整生存期。

可见生存期:活动在onStart()和onStop()之间经历的是可见生存期。在这一阶段,活动对于用户总是可见,即使可能无法与用户进行交互。因此我们应合理管理对用户可见的资源。如选择合适的时机对资源进行加载和释放。

前台生存期:活动在onResume()和onPause()之间经历的就是前台生存期。活动总是处于运行状态。

方法名 意义
onCreate() 活动第一次创建的时候调用,完成初始化操作,加载布局、绑定事件
onStart() 由不可见变为可见时调用
onResume() 与用户进行交互时调用,此时其一定处于栈顶并处于运行状态
onPause() 系统准备去启动或恢复另一个进程时调用,释放CPU资源保存关键数据
onStop() 活动完全不可见时调用
onDestroy() 活动被销毁之前调用,之后的状态变为销毁状态
onRestart() 活动重新启动

不难看出, 以上方法除了Restart外都是两两相对的。其中Stop和Pause方法的区别是如果新活动是对话框式的则pause会执行而stop不会。

活动的启动模式

standard 默认的启动模式。每启动一个新的活动,就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的活动,系统不会在乎活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。

singletop 在启动活动时如果发现返回栈顶的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。

singleTask 每次启动该活动时系统首先会在返回栈中检测是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出战,如果没有发现就会创建一个新的活动实例。

singleinstance 启用一个新的返回栈来管理这个活动。有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。

android:launchMode="singleinstantce"

退出程序

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 finishAll(){
        for(Activity activity:activities){
            if(!activity.isFinishing()){
                activity.finish();
            }
        }
    }
}

public class BaseActivity extends AppCompatActivity{
    protected void onCreate(Bundle savedInstanceState){
        /****/
        ActivityCollector.add(this);
    }
    protected void onDestroy(){
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

//android.os.Process.killProcess(android.os.Process.myPid());
//杀掉一个进程,接收进程ID参数。但此方法只能用于杀掉当前程序的进程,不能杀掉其他程序。

其他方法

getMenuInflater().infalte(R.menu.main,menu);	//创建互动菜单,(资源文件,传递目标对象)
finish();									//销毁活动
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章