您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
51_隐式意图和显示意图
发布时间:2021-03-01 18:42:44编辑:雪饮阅读()
两个activity
然后一般的,布局文件也需要新增一份,就直接拷贝activity_main.xml并命名为activity_main2.xml于原来的activity_main.xml在同一个目录即可activity_main2.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mutileactivity">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MutileActivity">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:label="@string/MainActivity2"
android:name=".MainActivity2" >
</activity>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
同样的,拷贝MainActivity.java为MainActivity2.java:
package com.example.mutileactivity;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity2 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
}最后就是清单文件中新增的activity的label的依赖值strings.xml中定义:
<resources>
<string name="app_name">MutileActivity</string>
<string name="MainActivity2">activity02</string>
</resources>打开一个指定的activity
建立了第二个activity后,如果要打开这个新建立的activity,可以在一个载体上(比如这里的原来的主activity)中比如以点击事件来完成。则在原来的布局文件中添加一个按钮activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="激活第二个activity"
android:onClick="open"
/>
</LinearLayout>为了区分原来的activity,看到更明显的效果,则在新的布局文件中将默认显示的内容区分下activity_main2.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="activity_main2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>然后在主程序中实现点击事件,并完成对应的打开一个指定activity的具体实现MainActivity.java:
package com.example.mutileactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view){
Intent intent = new Intent();
//待打开activity所在包名;待打开activity类名(包含包名的全路径)
intent.setClassName("com.example.mutileactivity", "com.example.mutileactivity.MainActivity2");
startActivity(intent);
}
}这样就能实现通过主activity中的一个按钮就可以打开新建的这个activity了
两个桌面图标
上面虽然完成了两个activity,但是如果想要两个activity都出现在桌面上的这种需求还是不能达成。默认情况下一个应用一个activity,桌面上显示的也是主activity,这里面虽然是两个activity,但是桌面上仍旧显示的只是主activity。
如果要想这第二个activity也显示出来,则在清单文件中还要将意图过滤段拷贝给新的activity,则AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mutileactivity">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MutileActivity">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:label="@string/MainActivity2"
android:name=".MainActivity2" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>然后部署到设备中就是两个图标了
第二种打开目标activity的方法
这种方法看起来更优雅,只需要待打开activity所在包的上下文件及待打开activity的类即可
在上面的MainActivity.java中修改下open方法:
package com.example.mutileactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view){
//待打开avtivity的包的上下文;待打开activity的类
Intent intent = new Intent(this,MainActivity2.class);
startActivity(intent);
}
}第三种打开目标activity的方法
这一种方法和第一种方法有点类似,MainActivity.java:
package com.example.mutileactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view){
Intent intent = new Intent();
ComponentName component = new ComponentName("com.example.mutileactivity", "com.example.mutileactivity.MainActivity2");
intent.setComponent(component);
startActivity(intent);
}
}显式意图
以上三种打开目标activity的方法称为显式意图,显式意图明确指明了启动活动的上下文和想要启动的目标活动,显式意图明确指定了Intent应该传递给哪个组件。
第四种打开目标activity的方法
该种方法需要提供Action、Category属性值,而清单文件AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mutileactivity">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MutileActivity">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:label="@string/MainActivity2"
android:name=".MainActivity2" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
</application>
</manifest>可以看出第二个activity我已经将那个category从意图过滤种删除掉了,虽然删除掉了,但是,一般没有声明,则表示使用的是”android.intent.category.DEFAULT”,所以MainActivity.java中的open实现如:
package com.example.mutileactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view){
Intent intent = new Intent();
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
}但是这样当你点击打开目标activity时候就会出现如下下拉选项
这是因为android.intent.action.MAIN这个action与android.intent.category.DEFAULT这个category进行意图筛选时候,在当前这个设备中结果有多条。
此时可以尝试将清单文件中这个新增的activity给修改下action的名称
<action android:name="android.intent.action.kasumi" />
然后MainActivity.java中对open方法修改如:
package com.example.mutileactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view){
Intent intent = new Intent();
intent.setAction("android.intent.action.kasumi");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
}但此时运行到设备中进行测试就会发现会报出如下错误
那么此时将<category android:name="android.intent.category.DEFAULT" />添加到刚才新增的activity中,则AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mutileactivity">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MutileActivity">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:label="@string/MainActivity2"
android:name=".MainActivity2" >
<intent-filter>
<action android:name="android.intent.action.kasumi" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>然后再次部署到设备中就又正常了,这就验证了即便意图过滤中没有添加任何category,也不会走默认的android.intent.category.DEFAULT的category。上面能出现下拉的时候是因为人家匹配的设备中的其它某些程序中有设置的android.intent.category.DEFAULT以及android.intent.action.MAIN
action与category的匹配条件可以多对出现
action与category的匹配条件可以多对,当存在多对action与category的匹配时表示本activity可以通过这多对中的每一对都可以找到。
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mutileactivity">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MutileActivity">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:label="@string/MainActivity2"
android:name=".MainActivity2" >
<intent-filter>
<action android:name="android.intent.action.kasumi" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.kasumi2" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>MainActivity.java:
package com.example.mutileactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view){
Intent intent = new Intent();
intent.setAction("android.intent.action.kasumi2");
intent.addCategory("android.intent.category.LAUNCHER");
startActivity(intent);
}
}这样也是可以正常通过按钮打开这个新建立的activity
通过隐式意图打开系统图库
这个意图过滤器中还可以添加data标签,大概如:
<data android:scheme="shttp"
android:host="a.b.c"
android:mimeType="image/**"
></data>这其中有一个mimeType,指定了要调用该activity时候的传参标准,个人理解意思是这里筛选要加上协议为shttp、主机位a.b.c然后mimeType为image/**时就能够精确匹配到本activity了,用以防止上面的action与category的匹配还是能得到更多匹配结果时所准备的。不过一般定义了这个data后,则在调用的地方就必须要传这个data所规定的一些信息。调用方式大致形如:
Intent intent = new Intent();
intent.setAction("cn.itcast.mutileactivity.xxx");
intent.addCategory("android.xxx");
intent.setData(Uri.parse("itcast://cn.itcast.demo"));
这里不做这个的具体演示。但是基于此可以知道,如果我们知道一个应用的action、category等信息或者data中mimeType等信息则可以去精准的调用这个应用。
无独有偶,系统中意图Intent类就提供了静态的一些action属性,可以通过ide能给予提示hint。并且像是image/jpeg这种常见的data中的mimeType正好是图库所具备的。另外就是Intent提供有一静态Intent.ACTION_PICK可以调用图片选取,则结合image/jpeg的mimeType就能筛选出系统中对于本程序拥有可读权限的一些图片列表出来了,也可以说是图库了。
那么具体实现则将open方法再次修改如:
package com.example.mutileactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void open(View view){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/jpeg");
startActivity(intent);
}
}运行到设备中并通过点击按钮后打开的效果则如:
然后这个图片选择器还可以打开每个item中的图片列表,这里只出现了一个item,点击后里面会有4个图片
隐式意图
像是上面从第三种方法之后的这些意图打开操作方法都称为隐式意图
隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。
关键字词:隐式意图,显式意图
相关文章
-
无相关信息