您的位置:首页 > 移动开发 > Android开发

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

2017-03-24 21:37 232 查看

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{
priva
4000
te 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/1
tel: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(bun
bee8
dle.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的返回数据
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: