Android学习记录0324-Intent详解及StartActivityForResult用法

来源:互联网 发布:mysql服务无法启动1067 编辑:程序博客网 时间:2024/06/18 15:26

Intent简介

Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。
Intent作用的表现形式:
- 通过Context.startActivity()或Activity.startActivityForResult()启动一个Activity;
- 通过Context.startService()启动一个服务,或者通过Context.bindService()和后台服务交互;
- 通过广播方法Context.sendBroadcast()\Context.sendOrderedBroadcast()\Context.sendStickyBroadcast()发给broadcastreceivers。

Intent属性

1.Component属性(组件)

Intent的Component属性需要接受一个组件名,Intent将直接启动指定的组件,因此这种Intent也被成为显式Intent,也是最常见的一种用法;没有指定Component属性的Intent则被成为隐式Intent,需要通过其他属性来确定需要启动哪个组件,如果intent指定了这个属性以后,其它所有属性都是可选的。
简化之后就是大家熟悉的形式了,用setClass方法添加指定的跳转组件,startActivity()来执行跳转任务。

        Intent intent=new Intent();        intent.setClass(this,Class_B.class);        startActivity(intent);

2.Action属性(动作)

Action是指Intent要完成的动作,是一个字符串常量。SDK中定义了一些标准常量,如下:
这里写图片描述

demo_1自定义action:

Class_A:

public class Class_A extends AppCompatActivity implements View.OnClickListener{    private Button btn;    private final static String B_ACTION="com.example.nedusoftware.jdbc_test.Class_B"; //自定义Action    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn=(Button) findViewById(R.id.btn_A);        btn.setOnClickListener(this);    }    @Override    public void onClick(View v) {        Intent intent=new Intent();        intent.setAction(Class_A.B_ACTION);//设置action属性        startActivity(intent);    }}

Class_B:

public class Class_B extends Activity {    @Override    protected void onCreate( Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.b);    }}

AndroidManifest文件中需要将Class_B声明一下action属性
注意:每一个filter中至少包含一个category属性,所以配置属性如下:

<activity android:name=".Class_B">            <intent-filter>                <action android:name="com.example.nedusoftware.jdbc_test.Class_B"/>                <category android:name="android.intent.category.DEFAULT" />            </intent-filter></activity>

Demo_2使用系统action常量:

Class_A:

        Intent intent=new Intent();        intent.setAction(Intent.ACTION_GET_CONTENT);//设置action属性        intent.setType("vnd.android.cursor.item/phone");//设置type属性        startActivity(intent);

3.Category属性

category(类别),被执行动作的附加信息。例如 LAUNCHER_CATEGORY 表示Intent 的接受者应该在Launcher中作为顶级应用出现。SDK中还给出了其他的信息:
这里写图片描述

Demo:

每个module中都有一个MainActivity,在AndroidManifest中的注册信息如下:

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

其中action表明此Activity是程序的入口,Category表明此应用为用户当前顶层应用。

4.Data属性

Data属性通常用于向Action属性提供操作的数据。Data属性接受一个Uri对象,一个Uri对象通常通过如下形式的字符串来表示:

content://com.android.contacts/contacts/1tel:123

Uri字符串总满足如下格式:

Scheme://host:port/path

例如上面给出的content://com.android.contacts/contacts/1,其中content是scheme部分,com.android.contacts是host部分,port部分省略了,/contacts/1是path部分。

5.type属性

Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。(就是type属性必须一致才能启动,也是在intent-filter中配置)。

6.Extra属性

Intent的Extra属性通常用于再多个Action之间进行数据交换,Intent的Extra属性值应该是一个Bundle对象,Bundle对象就像一个Map对象,它可以存入多个key-value对,这样就可以通过Intent在不同Activity之间进行数据交换了。

Demo Activity带值跳转:

a.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.example.nedusoftware.jdbc_test.Class_A">    <TextView        android:id="@+id/t_A"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!" />    <Button        android:id="@+id/btn_A"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="第一个Activity"/></LinearLayout>

b.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:id="@+id/t_B"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="这是第二个activity" /></LinearLayout>

Class_A:

public class Class_A extends AppCompatActivity implements View.OnClickListener{    private Button btn;    private TextView t_A;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.a);        btn=(Button) findViewById(R.id.btn_A);        t_A=(TextView) findViewById(R.id.t_A);        btn.setOnClickListener(this);    }    @Override    public void onClick(View v) {        Intent intent=new Intent();        Bundle bundle=new Bundle();        bundle.putString("test",t_A.getText().toString());        intent.setClass(this,Class_B.class);        intent.putExtras(bundle);        startActivity(intent);    }}

Class_B:

public class Class_B extends Activity {    private TextView t_B;    @Override    protected void onCreate( Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.b);        t_B=(TextView) findViewById(R.id.t_B);        Bundle bundle=this.getIntent().getExtras();        t_B.setText(bundle.getString("test"));    }}

这里写图片描述
这里写图片描述

StartActivityForResult用法

如果想在Activity中得到新打开Activity 关闭后返回的数据,需要使用系统提供的startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新的Activity 关闭后会向前面的Activity传回数据,为了得到传回的数据,必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法。

相关函数:

startActivityForResult(Intent intent, Int requestCode)
setResut(int resultCode, Intent intent)
onActivityResult(int requestCode, int resultCode, Intent intent)

Demo:

在Class_A中用startActivityForResult方法启动Class_B,并重写onActivityResult方法。

public class Class_A extends AppCompatActivity implements View.OnClickListener{    private Button btn;    private TextView t_A;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.a);        btn=(Button) findViewById(R.id.btn_A);        t_A=(TextView) findViewById(R.id.t_A);        btn.setOnClickListener(this);    }    @Override    public void onClick(View v) {        Intent intent=new Intent();        intent.setClass(this,Class_B.class);        startActivityForResult(intent,0);//启动新Activity    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(resultCode==RESULT_OK){            Bundle bundle=data.getExtras();            t_A.setText(bundle.getString("result"));        }    }}

Class_B中使用setResult方法添加结果,此方法必须在finish前调用。

public class Class_B extends Activity implements TextView.OnClickListener{    private Button btn_B;    @Override    protected void onCreate( Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.b);        btn_B=(Button) findViewById(R.id.btn_B);        btn_B.setOnClickListener(this);    }    @Override    public void onClick(View v) {        Intent intent=new Intent();        Bundle bundle=new Bundle();        bundle.putString("result","B中结果");        intent.putExtras(bundle);        setResult(RESULT_OK,intent);//调用setResult方法添加结果        this.finish();    }}

点击之前第一个Activity

点击打开新的Activity
这里写图片描述
第二个Activity finish掉之后返回结果
这里写图片描述

requestCode请求码的作用

使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮打开的,并且要做出相应的业务处理,这时可以这样做:

@Override  public void onCreate(Bundle savedInstanceState) {        ....        button1.setOnClickListener(new View.OnClickListener(){            public void onClick(View v) {                startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 1);           }        });        button2.setOnClickListener(new View.OnClickListener(){            public void onClick(View v) {                 startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2);            }        });       @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {               switch(requestCode){                   case 1:                   //来自按钮1的请求,作相应业务处理                   case 2:                   //来自按钮2的请求,作相应业务处理                }          }}

resultCode结果码的作用

在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,在onActivityResult()方法中可以这样做(ResultActivity和NewActivity为要打开的新Activity):

public class ResultActivity extends Activity {       .....       ResultActivity.this.setResult(1, intent);       ResultActivity.this.finish();}public class NewActivity extends Activity {       ......        NewActivity.this.setResult(2, intent);        NewActivity.this.finish();}public class MainActivity extends Activity { // 在该Activity会打开ResultActivity和NewActivity       @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {               switch(resultCode){                   case 1:                   // ResultActivity的返回数据                   case 2:                    // NewActivity的返回数据                }          }} 
0 0
原创粉丝点击