一、Intent作用及分类
Intent是一种消息传递机制,可以在程序内及程序间使用,主要用法为:①使用类名显式启动一个service或Activity②在①的基础上执行一个动作的intent,并进行相关处理③广播某个时间已经发生。
二、使用Intent启动Activity
1、显式启动一个Activity
所谓显式启动,即显式指定我们要启动Activity的类名,比如我们要在Mainactivity中的Button被按下时,打开IntentActivity,就可以使用下面的代码:
<span style="font-size:18px;"><span style="white-space:pre"> </span>if(v==btn1)
{
Intent intent=new Intent();
intent.setClass(MainActivity.this, IntentActivity.class);
startActivity(intent);
}</span>
注意,所有的Activity都存储于一个Activity栈,当我们调用startActivity后,IntentActivity将会经过Creat start resume最终运行,并且IntentActivity会移动到Acticity栈的顶部。但是当我们按下back(或在代码执行finish())会从Activity栈栈顶依次删除Activity。
2、隐式启动Activity
隐式启动Activity即匿名启动某一恰当的程序组件来响应动作请求。如我们要隐式的启动打开联系人的Activity:
<span style="font-size:18px;">//隐式选择联系人,注意使用startActivity并不能启动界面
Intent intent=new Intent(Intent.ACTION_PICK,Uri.parse("content://contacts/people"));
startActivityForResult(intent,PICK_CONTACT_SUBACTIVITY);</span>
3、启动Activity并捕获子Activity返回的结果
在上文我们可以看出,单纯使用startActivity MainActivity并不能得到IntentActivity进行处理后的结果。这时我们需要startActivityForResult:
但是仅仅使用这个接口还不够,我们需要一个接口来监听结构,这时,我们就需要重载MainActivity中的protected void onActivityResult(int requestCode, int resultCode, Intent data):
在MainActivity中:
<span style="font-size:18px;"><pre name="code" class="java"><pre name="code" class="java">//定义intent识别码
private static final int SHOW_SUBACTIVITY=1;<pre name="code" class="java">Intent intent=new Intent();
intent.setClass(MainActivity.this, IntentActivity.class);
//传入识别码唯一标识SHOW_SUBACTIVITY,启动intent,以便获取下一页面返回的结果
startActivityForResult(intent, SHOW_SUBACTIVITY);</span>
<span style="font-size:18px;"> @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==SHOW_SUBACTIVITY)
{
switch (resultCode) {
case RESULT_CANCELED:
{
Bundle bd=data.getExtras();
edittxt.setText(bd.getString("text"));
break;
}
case RESULT_OK:
{
Bundle bd=data.getExtras();
edittxt.setText(bd.getString("text"));
break;
}
default:
break;
}
}
}</span>
在IntentActivity中:
<span style="font-size:18px;">switch(v.getId())
{
case R.id.resultcancel:
{
Intent intent=new Intent();
intent.setClass(IntentActivity.this, MainActivity.class);
intent.putExtra("text", "cancel:i am from intentactivity!and pass back me on childactivity finished!");
setResult(RESULT_CANCELED,intent);
finish();
break;
}
case R.id.resultok:
{
Intent intent=new Intent();
intent.setClass(IntentActivity.this, MainActivity.class);
intent.putExtra("text", "ok: am from intentactivity!and pass back me on childactivity finished!");
setResult(RESULT_OK,intent);
finish();
break;
}
default:
break;
}</span>
解析:我们在startActivityForResult(intent, SHOW_SUBACTIVITY);传入SHOW_SUBACTIVITY,其实就是一个大于0的整数,用来标识相应的Intent;为了接受Result,对onActivityResult(int requestCode, int resultCode, Intent data) 进行重写,注意,requestCode就是Intent的标识符,即为上文中的SHOW_SUNACTIVITY,resultCode即为IntentActivity中的setResult(RESULT_OK,intent);传回的Result值 -RESULT_OK,date即为setResult(RESULT_OK,intent);传回的intent。
三、使用Intent广播事件
1、最基本的广播事件发送与接受:
广播的发送,很简单,生成一个Intent,设置Action,直接进行广播:
<span style="font-size:18px;"><span style="white-space:pre"> </span>public static final String BROAD_UI_STRING="com.example.intentbraodcast.BROAD_UI"; </span>
<span style="font-size:18px;"><span style="white-space:pre"> </span>Intent intent=new Intent(BROAD_UI_STRING);
intent.putExtra("str", "update ui by broadcast!");
sendBroadcast(intent);</span>
广播的注册,最好在广播的发送前注册广播:
<span style="font-size:18px;"><span style="white-space:pre"> </span>//注册Broadcast Receiver
registerReceiver(new MyBroadcastReceiver, new IntentFilter(BROAD_UI_STRING));</span>
注:上文中的 BROAD_UI_STRING就是一个自定义的独一无二的字符串,由于广播不但可用于应用程序内部交换数据,还可用于系统间应用交换数据,故一般用传统的包名前缀法来命名。
进行注册以前,我们需要实现自己的接收器,继承BroadcastReceiver即可,我们对广播出的Intent绑定的数据再次进行处理
<span style="font-size:18px;">public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO: React to the Intent received.
String actionString=intent.getAction();
if (actionString.equals(BROAD_UI_STRING))
{
//改变下一个activity中的值
String str=intent.getStringExtra("str");
Intent newIntent=new Intent();
newIntent.setClass(MainActivity.this,IntentActivity.class );
newIntent.putExtra("str", str);
context.startActivity(newIntent);
}
else if(actionString.equals(LOCAL_ACTION))
{
edittxt.setText(intent.getStringExtra("str"));
}
}
}</span>
广播的注销:在我们不再广播时,通常是界面挂起或停止时,需要对接收器进行注销:
<span style="font-size:18px;"> @Override
protected void onPause() {
unregisterReceiver(receiver);
super.onPause();
}</span>
需要注意的是,接收器中的处理程序需要在5秒钟内完成,否则会显示Force CLose的对话框。很多时候,我们希望当我们的应用程序在关闭时也能响应一些广播,需要在Manifest中的application节点添加一个receiver标签,指定接收器类名和过滤器标识符:
<span style="font-size:18px;"><receiver android:name=".MyBroadcastReceiver"
<intent-filter>
<action android:name="packagename.classname.BROAD_UI_STRING" />
</intent-filter>
</receiver></span>
这样,即使我们的应用程序处于关闭状态也能响应广播。
2、有序广播
3、广播Sticky Intent,在一些教程仍出现,但在android 5.0以后会渐渐废弃,故不再讨论。
4、LocalBroadcastManager(局部广播管理器)
顾名思义,其用于局部数据的消息驱动,是一种轻量级的handler,更高效的广播模型。
操作过程与普通广播管理器类似,只不过要先获取LocalBroadcastManager:
<span style="font-size:18px;">lbm=LocalBroadcastManager.getInstance(MainActivity.this);</span>
发送时将sendBroadcast改为lbm.sendBroadcast,注册时将registerReceiver改为lbm.registerReceiver,注销时将unregisterReceiver改为lbm.unregisterReceiver
下面为示例的全部代码,工程文件我也会放到最后:
<span style="font-size:18px;">package com.example.intentandbroadcast;
import android.R.string;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
@SuppressWarnings("unused")
public class MainActivity extends Activity {
Button btn1;
Button btn2,btn3,btn4,btn_broad_ui,btn_local_broad;
EditText edittxt;
TextView tv;
LocalBroadcastManager lbm;
MyBroadcastReceiver receiver;
//定义intent识别码
private static final int SHOW_SUBACTIVITY=1;
private static final int PICK_CONTACT_SUBACTIVITY=2;
public static final String BROAD_UI_STRING="com.example.intentbraodcast.BROAD_UI";
public static final String LOCAL_ACTION="com.example.intentbraodcast.LOCAL_ACTION";
void getviewdefinition()
{
btn1=(Button)findViewById(R.id.btn1);
btn2=(Button)findViewById(R.id.btn2);
btn3=(Button)findViewById(R.id.btn3);
btn4=(Button)findViewById(R.id.btn4);
btn_broad_ui=(Button)findViewById(R.id.btn_broad_ui);
edittxt=(EditText)findViewById(R.id.edittext);
tv=(TextView)findViewById(R.id.textview);
btn_local_broad=(Button)findViewById(R.id.btn_local_broad_ui);
lbm=LocalBroadcastManager.getInstance(MainActivity.this);
receiver=new MyBroadcastReceiver();
}
public class OnButtonClick implements OnClickListener
{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v==btn1)
{
Intent intent=new Intent();
intent.setClass(MainActivity.this, IntentActivity.class);
//传入识别码唯一标识SHOW_SUBACTIVITY,启动intent,以便获取下一页面返回的结果
startActivityForResult(intent, SHOW_SUBACTIVITY);
}
else if(v==btn3)
{
//触发外部intent打电话
Intent intent=new Intent(Intent.ACTION_DIAL,Uri.parse("tel:13237170570"));
startActivity(intent);
}
else if(v==btn4)
{
//隐式选择联系人,注意使用startActivity并不能启动界面
Intent intent=new Intent(Intent.ACTION_PICK,Uri.parse("content://contacts/people"));
startActivityForResult(intent,PICK_CONTACT_SUBACTIVITY);
}
else if(v==btn_broad_ui)
{
Intent intent=new Intent(BROAD_UI_STRING);
intent.putExtra("str", "update ui by broadcast!");
sendBroadcast(intent);
}
else if(v==btn_local_broad)
{
//设置本地广播,更高效:
Intent intent=new Intent(LOCAL_ACTION);
intent.putExtra("str", "i am created by local broadcast!");
lbm.sendBroadcast(intent);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getviewdefinition();
OnButtonClick btnclick=new OnButtonClick();
btn1.setOnClickListener(btnclick);
btn3.setOnClickListener(btnclick);
btn4.setOnClickListener(btnclick);
btn_broad_ui.setOnClickListener(btnclick);
btn_local_broad.setOnClickListener(btnclick);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
//注册Broadcast Receiver
registerReceiver(receiver, new IntentFilter(BROAD_UI_STRING));
//注册local broadcast
lbm.registerReceiver(receiver, new IntentFilter(LOCAL_ACTION));
}
@Override
protected void onPause() {
unregisterReceiver(receiver);
lbm.unregisterReceiver(receiver);
super.onPause();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==SHOW_SUBACTIVITY)
{
switch (resultCode) {
case RESULT_CANCELED:
{
Bundle bd=data.getExtras();
edittxt.setText(bd.getString("text"));
break;
}
case RESULT_OK:
{
Bundle bd=data.getExtras();
edittxt.setText(bd.getString("text"));
break;
}
default:
break;
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO: React to the Intent received.
String actionString=intent.getAction();
if (actionString.equals(BROAD_UI_STRING))
{
//改变下一个activity中的值
String str=intent.getStringExtra("str");
Intent newIntent=new Intent();
newIntent.setClass(MainActivity.this,IntentActivity.class );
newIntent.putExtra("str", str);
context.startActivity(newIntent);
}
else if(actionString.equals(LOCAL_ACTION))
{
edittxt.setText(intent.getStringExtra("str"));
}
}
}
}
</span>
<span style="font-size:18px;">package com.example.intentandbroadcast;
import java.security.PublicKey;
import com.example.intentandbroadcast.MainActivity.MyBroadcastReceiver;
import android.app.Activity;
import android.app.PendingIntent.CanceledException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
public class IntentActivity extends Activity {
Button cancel,ok,btn_local;
TextView txtintentTextView;
IntentFilter filter;
String stickystring;
void getdefinition()
{
cancel=(Button)findViewById(R.id.resultcancel);
ok=(Button)findViewById(R.id.resultok);
btn_local=(Button)findViewById(R.id.btn_localintent);
txtintentTextView=(TextView)findViewById(R.id.textintent);
}
public class OnBtnClick implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.resultcancel:
{
Intent intent=new Intent();
intent.setClass(IntentActivity.this, MainActivity.class);
intent.putExtra("text", "cancel:i am from intentactivity!and pass back me on childactivity finished!");
setResult(RESULT_CANCELED,intent);
finish();
break;
}
case R.id.resultok:
{
Intent intent=new Intent();
intent.setClass(IntentActivity.this, MainActivity.class);
intent.putExtra("text", "ok: am from intentactivity!and pass back me on childactivity finished!");
setResult(RESULT_OK,intent);
finish();
break;
}
default:
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//雷区,这个启动的xml打错了 调了好久
setContentView(R.layout.activity_intent);
getdefinition();
//测试startactivyforresult
cancel.setOnClickListener(new OnBtnClick());
ok.setOnClickListener(new OnBtnClick());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
</span>
eclipse工程地址:http://download.csdn.net/detail/tianyuan521521/8604875