- 浏览: 89227 次
文章分类
- 全部博客 (15)
- 强制刷新 (0)
- 动态设定 (0)
- android (10)
- source collect (0)
- tools (2)
- wireshark (2)
- java (1)
- RandomAccessFile (0)
- home key (0)
- surfaceview 居中 (0)
- 视频工具 (0)
- animation (0)
- net (0)
- 抓包 (0)
- MediaRecorder (1)
- listview (1)
- gridview (0)
- api demo (1)
- php (0)
- linux (0)
- movie (0)
- english (0)
- game (0)
- cygwin (0)
- object C (0)
- mina (1)
- tcp (0)
- udp (0)
- error (2)
- c++ (0)
- time (1)
- utc (1)
- gmt (1)
- ea (0)
- eap (0)
- uml (0)
- other (0)
- web (1)
- jnlp (1)
- sakai (1)
- demo (1)
- tomcat (1)
- sn (0)
- 缓存 (1)
- 网络连接 (1)
- clone (1)
- fragment (1)
最新评论
-
绿茵好莱坞:
好文 ,值得学习
如何让Android模拟器能访问到本地Server或Web应用(即:运行模拟器的PC) -
diyangxia:
看起来比较靠谱
Media start error原因分析及解决方法 -
whhpc19891120:
大哥,还是用了你的方法问题还是存在
Media start error原因分析及解决方法 -
dndxcsy:
好帖!总算在这里找到HH:mm:ss和hh:mm:ss会返回2 ...
Android系统时间制式的获取(24小时制式/12小时制式)及UTC与本地时间的转换
闲着没事儿,看了下Android API Demo的代码,发下他的框架写的挺有意思,特记录在这里,以便将来查阅。
I、整体的思路
熟悉或看过系统自带的API Demo的人,应该都有印象,根据各层demo的类别分组,每个组里面包包含示例activity,如下图:
如果要是手动实现这个效果,无非有两种方法:
1、前两层都创建一个Activity,每个Activity中都包含一个ListView, 在底层关联真正的demo代码
2、前两层都用ListActivity,在底层关联真正的demo代码
前两层的本质都是一样的,用ListView实现,这样做有一个麻烦的地方,就是需要创建很多个Activity(具体的个数视分组的个数而定),同样的
代码需要copy几次,麻烦。。
那么,有什么简便方法吗,看看API Demo,他是怎么做的?
1、如上面所说的使用 ListActivity(这个,跟咱们一般的想法一致)
2、用一个ListActivity实现分组或直接调用最终的demo代码
实现的原理就是在intent中筛选自己定义的intent组、保存到一个list中
II、API Demo的实现方式
下面是测试Demo从API Demo中摘出的代码,咱们分析下:
public class testActivity extends ListActivity { // 定义用于检索自己定义的Activity的Category的名称 public static final String CATEGORY_MYAPP_DEMO = "android.intent.category.MY_DEMO"; // 定义用于保存路径信息的键 public static final String PKG_PATH = "com.vs.apidemo.Path"; String TAG = "AUTO_TEST"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 获取保存的路径信息 Intent intent = getIntent(); String path = intent.getStringExtra(PKG_PATH); if (path == null) { path = ""; } // 设置ListActivity对应的List数据 setListAdapter(new SimpleAdapter(this, getData(path), android.R.layout.simple_list_item_1, new String[] {"title"}, new int[] {android.R.id.text1})); // 设置ListView可以根据用户输入的字串自动检索(当ListView获取焦点时) getListView().setTextFilterEnabled(true); Toast.makeText(this, "path=" + path, Toast.LENGTH_SHORT).show(); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { // 获取map中保存的intent Map map = (Map)l.getItemAtPosition(position); // 启动目标intent Intent intent = (Intent)map.get("intent"); startActivity(intent); } protected List getData(String prefix) { List<Map> myData = new ArrayList<Map>(); // 创建指定Action类型的Intent Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); // 添加到自己定义的Category中 mainIntent.addCategory(CATEGORY_MYAPP_DEMO); // 获取所有自己定义的Category的Activity信息,并保存到list中 PackageManager pm = getPackageManager(); List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0); // 如果没有符合条件的Activity,直接返回 if (null == list) return myData; // 定义保存路径的变量 String[] prefixPath; if (prefix.equals("")) { prefixPath = null; } else { // 将当前AA/B/C格式的路径转换为String数组{{AA},{B},{C}} prefixPath = prefix.split("/"); } // 获取满足条件的Activity的数目 int len = list.size(); Log.e(TAG, "list.size=" + list.size() + "\nlist:" + list.toString()); Map<String, Boolean> entries = new HashMap<String, Boolean>(); for (int i = 0; i < len; i++) { ResolveInfo info = list.get(i); /* * 获取Activity的label,此label即是在Manifest中,用“android:label="@string/activity_dialog"” * 定义的Activity label属性,具体参考Manifest文件 * label定义的是此Activity的路径 */ CharSequence labelSeq = info.loadLabel(pm); // 如果没有定义label值,则获取Activity定义的名称,即“android:name=”定义的字串 String label = labelSeq != null ? labelSeq.toString() : info.activityInfo.name; if (prefix.length() == 0 || label.startsWith(prefix)) { // 将路径名称转换为数组 String[] labelPath = label.split("/"); // 获取下层目录的名称 String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length]; // 如果顶层是测试Activity或最下一层的Activity时,设置启动的Activity为测试Activity if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) { // 以Activty的label为键,将对应的启动Activity的Intent保存到list中 addItem(myData, nextLabel, activityIntent(info.activityInfo.applicationInfo.packageName, info.activityInfo.name)); } else { // 如果还是目录,且该目录没有保存过,则保存 if (entries.get(nextLabel) == null) { /* * 以目录为键,将启动[本]Activity的Intent保存到list中 * 注意了,这里是本Activity,所有的目录嵌套的迁移实际上都是复用一个Activity * 正是这个处理,简化了代码~~ */ addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel)); entries.put(nextLabel, true); } } } } // 排序 Collections.sort(myData, sDisplayNameComparator); return myData; } /** * 使用Collator对字串进行排序 */ private final static Comparator<Map> sDisplayNameComparator = new Comparator<Map>() { private final Collator collator = Collator.getInstance(); public int compare(Map map1, Map map2) { return collator.compare(map1.get("title"), map2.get("title")); } }; /** * <创建启动Demo Activity用的Intent> * @param pkg 包名 * @param componentName Activity的name,即Manifest里面name指定的名称 */ protected Intent activityIntent(String pkg, String componentName) { Intent result = new Intent(); result.setClassName(pkg, componentName); return result; } /** * <创建启动本Activity用的Intent> * @param path 路径 */ protected Intent browseIntent(String path) { Intent result = new Intent(); // 启动本Activity用的Intent result.setClass(this, testActivity.class); // 将路径传递给下层目录,即在onCreate需要取出的数据 result.putExtra(PKG_PATH, path); return result; } /** * <将所有路径下对应启动Activity要用的Intent保存到list中> * <功能详细描述> * @param data 保存的list * @param name 键 * @param intent 启动Activity用的Intent */ protected void addItem(List<Map> data, String name, Intent intent) { Map<String, Object> temp = new HashMap<String, Object>(); temp.put("title", name); temp.put("intent", intent); data.add(temp); } }
通过上面的代码,可以看出,复用是通过如下几步完成:
1、先根据Category筛选出自己定义的Activity
2、再根据Activity的label解析路径
3、然后根据路径判断,如果是最后一层,则将启动测试demo的Intent保存到Map中,如果不是,则重复调用本Activity
思路很像递归。
上面提到label,咱们看看它在的Manifest的定义吧:
<application android:icon="@drawable/icon" android:label="@string/app_name"> <!--默认启动Activity--> <activity android:name=".app.testActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!--Demo Activity 注意: 1、label定义字串必须是他的实际路径 2、必须指定Activity的action为android.intent.action.MAIN 3、必须指定Activity的Category为android.intent.category.MY_DEMO这个与代码中定义的一致 要是1不满足,显示的可能就不是想要的分组了 要是2、3不满足,Activity就筛选不出来了--> <activity android:name=".app.CustomDialogActivity" android:label="@string/activity_custom_dialog" android:theme="@style/Theme.CustomDialog"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.MY_DEMO" /> </intent-filter> </activity> <activity android:name=".app.DialogActivity" android:label="@string/activity_dialog" android:theme="@android:style/Theme.Dialog"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.MY_DEMO" /> </intent-filter> </activity> </application>
下面是label字串的定义(strings.xml中):
<string name="activity_custom_dialog">App/Activity/Custom Dialog</string> <string name="activity_dialog">App/Activity/Dialog</string>
嗯,差不多就这样了~~
发表评论
-
Android类参考---Fragment(一)
2015-01-10 08:56 16821 继承关系 java.lang.Object |__ ... -
Activity的四种加载模式 -- singleTask 和 singleInstance模式
2014-03-07 10:54 4622Activity的启动模式可以通过AndroidMani ... -
如何让Android模拟器能访问到本地Server或Web应用(即:运行模拟器的PC)
2013-08-29 14:44 7671I、让人烦躁的问题 近日,在移植Mina框架到Androi ... -
Eclipse中运行程序,提示ADB server didn't ACK failed to start daemon
2013-07-26 15:32 1560今天在eclipse中运行程序时,提示: ADB ser ... -
【转载】 Android ListView性能优化之视图缓存
2013-07-19 16:31 1026转载自: 博客园:http://www.cnblo ... -
android 错误解决方法 ---积累中
2013-07-18 10:19 54241 在android编程中出现cannot be reso ... -
android htttp 下载
2013-03-20 15:04 0ttt -
Android系统时间制式的获取(24小时制式/12小时制式)及UTC与本地时间的转换
2013-03-01 10:59 13053I、获取系统时间制式(12小时制/24小时制) 1 ... -
android error
2013-01-10 18:17 0android 模拟器 Installation error: ... -
android mina使用
2012-12-25 17:39 0http://wmiao89620.iteye.com/blo ... -
android + js
2012-12-04 17:17 0Android中 Js 扩展及交互 . http://blog ... -
Android 资料
2012-12-03 10:08 0http://blog.csdn.net/tangcheng_ ... -
GridView或ListView 中android:drawSelectorOnTop的用法(转)
2012-09-28 16:04 0android:drawSelectorOnTop=&quo ... -
Media start error原因分析及解决方法
2012-09-28 09:09 5255之前在项目的时候,遇到到Media Recorder在快速启动 ... -
android 抓包方法
2012-09-13 19:35 0看到网上有朋友写了一个手机抓包工具,是一个apk,直接安装 ... -
anroid画面平滑上移
2012-08-30 21:29 0http://blog.csdn.net/pgalxx/art ... -
PreferenceActivity
2012-08-28 22:46 0SystemSetAcitivity.java pub ... -
android退出对话框
2012-08-24 17:39 0private void showExitDialog() ... -
surfaceview 居中
2012-08-20 17:54 0<LinearLayout xmlns:android= ... -
android源代码
2012-08-16 22:48 04.0 http://download.csdn.net/d ...
相关推荐
本项目“Android mvvm 框架,最流行的mvvm demo”旨在提供一个无bug的示例,帮助开发者深入理解并实践MVVM框架在Android应用中的应用。 MVVM模式源于微软的WPF开发,近年来在Android开发中逐渐流行,它通过解耦视图...
通过分析和理解它的源代码,开发者可以掌握如何在Android应用中集成高质量的VoIP功能。尽管存在一些潜在的错误,但只要细心研究并结合其他学习资源,就能从中受益匪浅。对于新手来说,这是一个很好的动手实践项目,...
在Android应用开发中,MVC(Model-View-...总的来说,这个"android开发MVC框架demo"项目提供了一个实际应用MVC模式的实例,通过学习和实践,开发者可以掌握如何在Android开发中有效地组织代码,提升应用的质量和效率。
《深入探索Android 4.4 API Demo》 在Android开发领域,API Demo是开发者们学习新版本API的重要参考资料。本文将详细解析Android 4.4(KitKat)的API Demo,帮助开发者理解并掌握这一版本的新特性、API用法以及系统...
4. **OpenGL ES**: Android游戏开发常依赖于OpenGL ES,这是一个用于2D和3D图形渲染的API。学习顶点坐标、纹理映射、着色器语言(GLSL)等概念,是创建动态视觉效果的关键。 5. **游戏引擎**: 对于复杂游戏,可以...
GreenDao是一个流行的ORM(Object-Relational Mapping)框架,专为Android设计,能够帮助开发者高效地操作SQLite数据库。本教程将通过一个名为"MyGreenDao"的示例项目,详细介绍如何在Android Studio中使用GreenDao...
本Demo主要展示了如何在Android平台上使用各种数据库框架,包括SQLite、ORM(对象关系映射)框架如Room、GreenDao等,以及一些流行的第三方库如Realm和SugarORM。下面将详细介绍这些数据库框架的使用方法。 1. ...
在Android应用开发中,MVP(Model-View-Presenter)架构是...在分析和学习这个demo时,关注各个层之间的通信方式,理解Presenter如何协调Model和View,以及如何适当地处理Android特有的生命周期问题,都是至关重要的。
本“android游戏小Demo”就是一个很好的起点,它提供了基础的游戏开发框架,帮助学习者理解Android游戏开发的基本概念和流程。 首先,我们来讨论Android游戏开发的基础。Android游戏通常基于Java或Kotlin语言编写,...
ijkplayer 是一个开源的跨平台多媒体框架,最初由 FFmpeg 项目的一个分支发展而来,特别适合于嵌入式设备和移动平台。它在 Android 上被广泛用于开发视频播放器应用,因为其高效的性能和对多种视频格式的支持。在这...
本项目"Android邮件客户端Demo"提供了一个全面的解决方案,采用JavaMail框架来实现这一功能。JavaMail是Java编程语言中的一个开源库,用于处理邮件相关的API,包括SMTP、POP3和IMAP等协议。 1. **JavaMail框架**:...
【Android五子棋Demo】是一个专门为Android平台设计的五子棋游戏示例...通过对源代码的阅读和学习,开发者可以深入理解Android应用的架构,掌握游戏逻辑的实现方法,以及如何利用Android API创建引人入胜的用户体验。
这些demo通常与Android的经典应用程序开发同步更新,确保开发者能够掌握最新的API和技术趋势。 "ApiDemos"这个压缩包文件名暗示了它包含的是Android API的演示代码。ApiDemos项目是Android SDK的一部分,它展示了一...
在Android应用开发中,Model-View-Presenter(MVP)是一种设计模式,它将业务逻辑、用户界面和数据处理分离开来,提高了...通过分析这个Demo,开发者可以学习到如何设计和实现MVP架构,以及如何在实际项目中应用它。
开发者可以通过解压并导入Android Studio来运行和分析代码,以学习PaddleOCR在Android环境中的应用。项目中可能包括以下关键组件: 1. **模型文件**:PaddleOCR的预训练模型,用于文字检测和识别。 2. **Java/ ...
标题"android camera2 google官方demo"表明这是一个基于`Camera2` API的示例项目,由Google官方提供,用于帮助开发者理解和学习如何使用新的相机框架。这个官方示例通常包含完整的代码实现,涵盖了许多关键功能,如...
通过分析这个“京东商城android demo”,我们可以深入学习到Android应用开发的多个方面,包括网络通信、数据存储、UI设计、权限管理、第三方服务集成以及性能优化等。这对于希望提升Android开发技能或了解电商应用...
在这个"正方体 demo"中,开发者首先会设置一个OpenGL ES环境,这是Android设备上进行3D图形渲染的标准框架。他们将创建一个正方体的几何模型,包括顶点、颜色和纹理坐标,然后使用OpenGL ES的Shader语言(GLSL)来...
Android ijkplayer的DEMO是基于开源媒体框架ijkplayer的一个示例项目,旨在帮助开发者理解和应用ijkplayer在Android平台上的播放功能。ijkplayer是由Bilibili开发并维护的跨平台多媒体框架,它支持多种视频和音频...
4. 深入理解Android框架:了解Android系统的运行机制,为系统级开发打下基础。 四、使用与调试 在使用ApiDemos时,可以通过以下步骤进行学习和实践: 1. 下载并导入项目:将ApiDemos项目导入Android Studio,确保...