最近开始研究Android,基础部分看得个大概,在这方面的教程和心得也比较的杂,还是决定一步一步跟着官方的实例来逐步深入android.
官方实例可以在安装SDK时勾选下载,通过新建Android项目(从已有项目新建)来导入源代码。官方的实例分为许多大类,层层深入,其中Android开发最基础的包和类的运用几乎囊括在ApiDemos之中。
将ApiDemos在模拟器中启动,会发现其并不是按照每个单独的实例分别需要多次安装启动,ApiDemos有一个统一的管理界面,也就是所谓的ListActivity,其实现类就是ApiDemos项目的入口类ApiDemos.java(此处有两种解释,实际上ApiDemos只是一个入口Activity,从根本上来说,ApiDemosApplication才是整个项目的入口类,ApiDemosApplication中进行了程序的初始化操作,实际上它所作的是用户喜好设定等的初始化操作。)
ApiDemos代码如下,根据自身理解,已经为其添加了部分注释:
package com.example.android.apis;
import android.app.ListActivity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
* 该类所做的主要操作是根据AndroidMainfest.xml文件中,各个Activity的Label名称,构建分层结构,并且根据
* 各个分层结构的特性,生成特定的ListView,并添加相应的Intent等.
* 如:android:label="App/Activity/Hello Wrold",ApiDemos会根据该Label标示的目录结构,生成三层ListView.
* 前两层Item的名称分别为App和Activity,在点击时会调用指向ApiDemos.class自身的Intent,进入下层View
* 在点击第三层的名为Hello Wrold的Item时,才会调用跳转到相应Activity的Intent.
*/
public class ApiDemos extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//获取Intent,用以监听源Activity究竟为何,并且获取上层目录路径
Intent intent = getIntent();
String path = intent.getStringExtra("com.example.android.apis.Path");
//若为初次调用ApiDemos或者当前目录为最底层目录(即:当前Activity中的Item点击会跳转Activity),则设置路径为空
if (path == null) {
path = "";
}
/*为ListActivity设置适配器,添加适配数据集合.获取源List(即getData(path))中的Key为title的元素作为ListView的Item
*Adapter大体分为以下3种:
*ArrayAdapter根据一个Array数组进行适配.
*SimpleAdapter的源是一个以Map为元素的List集合.可以根据键查询
*CursorAdapter主要用于数据库操作
*/
setListAdapter(new SimpleAdapter(this, getData(path),
android.R.layout.simple_list_item_1, new String[] { "title" },
new int[] { android.R.id.text1 }));
//设置是IntentFilter生效,即AndroidMainfest.xml中配置的intent-filter
getListView().setTextFilterEnabled(true);
}
//该方法用于初始化SimpleAdapter所需要的源数据
protected List getData(String prefix) {
List
所有预先在AndroidMainfest.xml中定义的Activity都可以根据ApiDemos以特定的规则匹配的到,目前为止,所有的Activity实际上以一种直观的层级结构展现.这便是ApiDemos所做的工作.
现在问题是,如果需要重新写一个类似于ApiDemos的统一管理入口ListActivity,可以直接copy代码解决么?
实验了一下,如果直接copy代码,表面来看是可行的,但是深入了解,却发现这种方法在某种程度上还是有些许缺憾.
我的新项目MyActivity的AndroidMainfest.xml定义如下:
package="com.my.android.app"
android:versionCode="1"
android:versionName="1.0">
android:label="@string/app_TextView">
android:label="@string/app_ButtonView">
android:label="@string/other_TextView">
我定义了3个和Apidemos不同的Activity,获取Activity的代码如下:
List myData = new ArrayList();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
intent.addCategory(Intent.CATEGORY_TEST);
PackageManager pm = getPackageManager();
List list = pm.queryIntentActivities(intent, 0);
一切就绪后,在模拟器上运行该程序.得到的结果有两种,但无非都不是预期的结果.
关键问题是在通过Intent查找Activity时,因为新项目中使用的IntentFilter和ApiDemos中相同,在查找Activity时,系统不仅会查找出新定义的3个Activity,还会一并查询出ApiDemos中定义的条件匹配的Activity,所以造成了可能会产生的非预期结果.
目前来说,我并未找到一个合适的方法来避免这种状况的发生,只能用一种很不贴切的方式来解决这一问题,那就是在.xml中Activity的intent-filter中添加另外的CATEGORY来作为查询条件,但是由此产生的Filter问题又会随之而生.目前还未发现合适的解决办法.
就到这里,这算是ApiDemos入口Activity的一个整体概述了.