apidemo代码分析

本文通过对ApiDemos的代码分析,揭示了其启动流程和Activity管理机制。ApiDemos使用ListActivity构建树形目录,根据目录结构进行Activity跳转。分析了label和prefix两类信息的作用,探讨了优化的可能性。
摘要由CSDN通过智能技术生成

分析代码,首先查看Androidmanifest.xml文件中的启动activity,如下所示:

        <activity android:name="ApiDemos">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    通过名为"LAUNCHER"的category,可以知道Apidemo首先启动的activity是ApiDemos,我们就从ApiDemos.java开始分析。通过在模拟器中运行ApiDemos,可以看到ApiDemos包含了许多单独的实例,那么程序是如何组织起这些实例的呢?通过下面对具体代码的分析,我们可以发现实际上ApiDemos.java中提供了一个统一的管理界面,这个管理界面包含了一个树形结构的目录,这个树形结构的目录就是通过ListActivity实现的。

    此处结合着网上一些人对ApiDemos.java文件的解析,为代码添加进去了自己的注释。如下所示:

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;

/* 
* ApiDemos类通过解析AnadroidManifest.xml文件中注册的各个Activity的label信息,生成应用程序的各级显示目录。
* label信息约定为此Activity的目录信息,例如DialogActivity的label的信息为“@string/activity_dialog”,
* 即为“App/Activity/Dialog”。也就是想要运行DialogActivity,需要先进入第一级目录的App,然后第二级目录的
* Activity,最后点击第三级目录的Dialog,就会出现DialogActivity的运行效果。
*/  
public class ApiDemos extends ListActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //获取启动此Activity的Intent
        Intent intent = getIntent();
        //获取到Intent中附带的path信息,在第一级目录中此path信息为空
        String path = intent.getStringExtra("com.example.android.apis.Path");
        
        if (path == null) {
            path = "";
        }
        
        /*
         * 此处并没有使用setContentView()函数来加载一个layout文件,而是使用setListAdapter(ListAdapter)
         * 函数自动的加载一个ListView的显示。ListAdapter可以使用的子类包括:arrayAdapter, SimpleAdapter,
         * CursorAdapter。此处新建了一个SimpleAdapter,其list数据源data通过getData()函数获得。
         */
        setListAdapter(new SimpleAdapter(this, getData(path),
                android.R.layout.simple_list_item_1, new String[] { "title" },
                new int[] { android.R.id.text1 }));
        /*
         * 相当于“ListView lv = getListView(); lv.setTextFilterEnabled(true);”。
         * 为ListView添加过滤功能,这一在某一级目录下根据用户输入的前几个字母,只显示过滤后相匹配的列表项。
         */
        getListView().setTextFilterEnabled(true);
    }

    
    // 该方法用于获取当前所在的目录信息,并生成SimpleAdapter中list项。
    protected List<Map<String, Object>> getData(String prefix) {
    	//新建一个名为myData的List,用于返回。
        List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();

        //新建一个action为MAIN的Intent
        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        //限定Intent的category为SAMPLE_CODE。这就限定了该Intent只能跳向符合这两项的Activity。
        mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);

        //建立一个包含全局包信息的PackageManager实例pm
        PackageManager pm = getPackageManager();
        //获取到所有可以由mainIntent跳转的Activity信息,返回值为List<ResolveInfo>
        List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);

        
        if (null == list){
        	return myData;
        }
        // 字符串数组prefixPath用于存放目录中去除“/”后的各个目录名字, 
        String[] prefixPath;
        //字符串prefixWithSlash用于存放目录名
        String prefixWithSlash = prefix;
        
        if (prefix.equals(""))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值