前言
在前面的博客中,对开启相机扫码到处理结果整个流程进行了基本的分析。而 Zxing 安卓端除了解码,还提供了创建二维码的功能
在主界面 CaptureActivity 的 onOptionsItemSelected 方法中,就有对点击“创建二维码”按钮后的处理操作:
case R.id.menu_share:
intent.setClassName(this, ShareActivity.class.getName());
startActivity(intent);
break;
Intent可以通过 startActivity(Intent intent) 显式启动新的Activity,在创建Intent时,直接指定类名称:Intent intent = new Intent(this , activity.class)
由此可以得知,在点击按钮后,启动了一个新的 Activity——ShareActivity,本次代码分析将以此为中心展开
一、Activity 的意图跳转
在分析代码中发现,ShareActivity 主要承担了一个功能选择页面的作用,根据其上的不同按钮和输入框,跳转到了相应的页面进行具体处理。其中应用到了 Activity 的意图跳转方法,因此这里先作一下简要介绍:
在进行界面间的跳转和传递数据的时候,我们有的时候要获得跳转之后界面传递回来的状态,数据等信息。这个时候,我们不一定需要使用Intent进行跳转回原先设置的界面,而是使用onActivityResult方法就可以解决这个问题
假设有A、B两个Activity,由A跳转到B,然后B返回到A,那么流程如下:
- 在A中调用startActivityForResult()方法来启动B
- 在B中调用setResult()方法来传递返回结果
- 在A中的 onActivityResult()方法中解析返回的结果,并做相应的逻辑操作
二、代码分析
onCreate
对于 ShareActivity ,其进入后会依次执行生命周期方法:
在 onCreate
方法中,主要进行了页面的初始化,将资源文件中的布局文件加载到 ShareActivity 中去,同时为各个按钮设置监听器
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// 加载布局文件
setContentView(R.layout.share);
// 为“分享联系人” 按钮设置监听
findViewById(R.id.share_contact_button).setOnClickListener(contactListener);
// 只有在SDK版本小于23时才能使用“分享书签”按钮
if (Build.VERSION.SDK_INT >= 23) {
findViewById(R.id.share_bookmark_button).setEnabled(false);
} else {
// 为“分享书签” 按钮设置监听器
findViewById(R.id.share_bookmark_button).setOnClickListener(bookmarkListener);
}
// 为“分享应用” 按钮设置监听器
findViewById(R.id.share_app_button).setOnClickListener(appListener);
// 为“分享剪切板” 按钮设置监听器
clipboardButton = findViewById(R.id.share_clipboard_button);
clipboardButton.setOnClickListener(clipboardListener);
// 为文字输入框设置监听器
findViewById(R.id.share_text_view).setOnKeyListener(textListener);
}
ShareActivity 显示页面如图:
监听操作
当点击不同按钮后,所进行的操作如下:
注意到在监听方法中,只有点击“分享联系人”、“分享应用”和“分享书签”这三个按钮使用的方法是 startActivityForResult(Intent intent, int requestCode)
而在点击“分享剪切板”按钮和在输入框输入文字都只是使用了 startActivity(Intent intent)
,因此进行这两项操作,跳转到 EncodeActivity 后,并不会返回到 ShareActivity
setResult
这里我们以点击“分享应用”后,跳转到的 AppPickerActivity 为例,来看一下在子页面是如何调用 setResult 方法的:
AppPickerActivity 继承了 ListActivity,其在 onResume 方法中,创建了一个后台任务 LoadPackagesAsyncTask
类的实例,主要作用是利用 Android 提供的 PackageManger 应用程序包管理类,来获取应用程序信息
最终在 AppPickerActivity 中陈列:
当点击其中一项时,所进行的处理如下:
protected void onListItemClick(ListView l, View view, int position, long id) {
// 要完成数据和界面的适配,需要设置 Adapter
Adapter adapter = getListAdapter();
if (position >= 0 && position < adapter.getCount()) {
// 获取应用程序包的名称
String packageName = ((AppInfo) adapter.getItem(position)).getPackageName();
Intent intent = new Intent();
intent.addFlags(Intents.FLAG_NEW_DOC);
// 拼接应用包url
intent.putExtra("url", "market://details?id=" + packageName);
// 发送结果给 ShareActivity
setResult(RESULT_OK, intent);
} else {
setResult(RESULT_CANCELED);
}
finish();
}
onActivityResult
返回到 ShareActivity 的 onActivityResult()方法,可知其主要对 “分享应用” 和 “分享联系人” 返回的结果进行了处理
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
// 分享书签
case PICK_BOOKMARK:
// 分享应用
case PICK_APP:
showTextAsBarcode(intent.getStringExtra("url"));
break;
// 分享联系人
case PICK_CONTACT:
showContactAsBarcode(intent.getData());
break;
}
}
}
而分析 showTextAsBarcode 和 showContactAsBarcode 方法,都是最终封装了一个 Intent 对象,跳转到了 EncodeActivity
因此总结来看,在 ShareActivity 中,就是针对不同的创建二维码操作,解析出文字(url)内容,传递给 EncodeActivity 处理。
总结
通过本次代码分析,了解了Android 的意图跳转方法。同时得知 ShareActivity 就是 EncodeActivity 的入口,具体对文字进行的编码操作都放到了 EncodeActivity 中进行,因此下次代码会重点分析 EncodeActivity 的内容