Android传递信息-Intent

Intent详细解释:

Intent是一种意图,用于启动Activity、Service、BroadcastReceiver

类型  方法
Activity    startActivity(Intent intent)
            startActivityForResult(Intent intent, int requestCode)
Service ComponentName startService(Intent service)
           boolean bindService(Intent service, ServiceConnection conn, int flags)
BroadcastReceiver   sendBroadcast(Intent intent)
                     sendOrderedBroadcast(Intent intent, String receiverPermission)

右侧的方法都是在Context中(除了startActivityForResult),而且Activity和Service都是Context的子类,就是在Activity和Service中都能启动三大组件

Android传递信息-Intent_第1张图片
1.png

Intent有7个属性:Action、Category、Data、Type、Extra、Flag、Compontent

Intent有两种启动方式:显示启动(指定找XXX)、隐式启动(指定条件,比如是一个大美女)

七大属性

[Compontent]

适用于显示启动,表示来源(就是上下文参数)和启动的目的地(要启动的组件)

三个构造函数:

ComponentName(String pkg, String cls)

ComponentName(Context pkg, String cls)

ComponentName(Context pkg, Class cls)

启动另外一个App中的Activity

第一个可以用来启动第二个APP中的Activity:

//指定另外一个APP的包名和类名
ComponentName name = new ComponentName("com.summer.test", "com.summer.test.MainActivity");
Intent intent = new Intent();
intent.setComponent(name);
startActivity(intent);

注意第二个参数要写全名,这样可以启动包名是com.summer.test中的MianActivity

启动本App中的Activity

指定上下文和对应的组件名:

     ComponentName name = new ComponentName(MainActivity.this, "com.summer.test.Main2Activity");
//两种方法一个是直接写出全名,一个是写出class
//        ComponentName name = new ComponentName(MainActivity.this, Main2Activity.class);
        Intent intent = new Intent();
        intent.setComponent(name);
        startActivity(intent);

简化写法

Intent intent = new Intent(MainActivity.this, Main2Activity.class);
startActivity(intent);
[Category和Action]

Action表示一个具体的动作,Categoey是Action增加的额外信息。在隐式启动中要给三个组件添加子标签而intent-filter子标签可以有action、category、data。Data和Type属性都在data标签内。

即使没有指定特定的Category系统会默认添加一个的标签。

在intent-filter中可以有多个action和category,但是最多只能有一个data标签,action和category的本质就是一个字符串,用name属性表示,比如主启动Activity:


    
        
 
        
    

隐式启动

启动Mian3Activity的代码:

Intent intent = new Intent();
intent.setAction("com.summer");
startActivity(intent);

    
        
    

这时会报错:
No Activity found to handle Intent {act=com.summer}

这是因为系统默认会给intent添加值是android.intent.category.DEFAULT的category,更改注册文件,可以启动


    
        
        
    

当两个Activity的注册文件当Action相同,但是category不同,那么只要action和intent匹配就可以启动,AndroidManifest文件:


    
        
        
    



    
        
        
        
    

Activity的启动代码:

Intent intent = new Intent();
intent.setAction("com.summer");
startActivity(intent);
[Extra]

Intent额外携带的数据,用putXXX来携带各种类型的数据,用getXXXX来获得数据,更改上面的案例,Activty1的发送代码:

Intent intent = new Intent();
intent.putExtra("hello","你好啊");
intent.setAction("com.summer");
startActivityForResult(intent,0);

Activity2的处理代码,就是给原有数据添加一句话:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        String hello = getIntent().getStringExtra("hello");
        hello += "-----这时来自Activity2的问候";
        Intent result = getIntent().putExtra("hello", hello);
//      打印Activity2正在处理
        System.out.println(getLocalClassName()+"正在处理数据-------"+hello);
        setResult(1,result);
    }

Activity1的回调代码:

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode,resultCode,data);
//      打印结果码
        System.out.println(resultCode);
//      打印处理之后的结果
        System.out.println(getLocalClassName()+"处理之后的数据是------"+data.getStringExtra("hello"));
    }
[Data和Type]

Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。

Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行判定。只要Type负责abc/xyz格式的字符串都可以。

Data和Type在单独指定的时候会相互覆盖,同时指定来两个值使用:setDataAndType方法

Data的匹配规则

Data的参数类型是Uri,例如content://win.hao.ty/data/1

Uri对应的名称是scheme://host/path 三个部分,在host后面可能有port相当于端口号

scheme、host、path是一个范围递减的三个属性(从大到小),就是某一个注册Activity只是指定了scheme属性,那么所有的Intent的Data属性只要以对应字段开头都会匹配

具体匹配实例

有这样三个Activity


     
         
         
         
     
 
 
 
     
         
         
         
     
 
 
 
     
         
         
         
     
 

对应的Intent如下,分别注释掉不同的赋值语句在启动的时候就会打开几个Activity

       
Intent intent = new Intent("com.summer");

//       只是启动一个Activity

        
intent.setData(Uri.parse("[hao://](hao://)"));

//      启动了两个Activity

        
intent.setData(Uri.parse("[hao://tianyi](hao://tianyi)"));

//       启动了三个Activity

        
intent.setData(Uri.parse("[hao://tianyi/datas/1](hao://tianyi/datas/1)"));

        
startActivity(intent);
[Flag]

Flag经常和Activity的启动模式一起来玩,Activity的四种启动模式:

默认模式

standard:不管这个Activity是否在栈中,都执行new操作,假如:栈中顺序是A B C D ,此时D通过Intent跳转到A,那么栈中结构就变成 A B C D A ,点击返回按钮的 显示顺序是 D C B A,依次摧毁。

对应的flag:Intent.FLAG_ACTIVITY_NEW_TASK

当目标Activity的affinity的属性和这个Activity相同时,就完全是默认模式,否则就是在一个新栈的默认模式

SingleTop

singleTop:永远在栈顶,当前Activity D位于栈顶的时候,如果通过Intent跳转到它本身的Activity (即D),那么不会重新创建一个新的D实例,所以栈中的结构依旧为A B C D,如果跳转到B,那么由于B不处于栈顶,所以会新建一个B实例并压入到栈中,结构就变成了A B C D B。

对应flag:FLAG_ACTIVITY_SINGLE_TOP

SingleTask

singleTask:也是永远在栈顶,不过当要启动的D不再栈顶时,会把上面的Activity全部干掉

对应flag:FLAG_ACTIVITY_CLEAR_TOP

SingleInstance

singleInstance:所有栈内只有一个实例,当启动D时,会先新建一个栈,然后再把D入栈

其他flag

FLAG_ACTIVITY_NO_HISTORY 一旦退出,它不会在栈内,比如:原来是A,B,C这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。

你可能感兴趣的:(Android传递信息-Intent)