`
guoxinzz
  • 浏览: 428844 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

定制你自己的android手机桌面Launcher===一个完成Launcher开发的介绍-第二篇

阅读更多

launcher也就是我们的Home,可以简单地把它理解为一个简化的linux GUI。作为一个GUI它首先必须完成它最本分的功能,
就是它必须能提供对所有应用程序(CATEGORY_LAUNCHER)的映射;不过作为一个 GUI,它除了做好本分之外还必须是符合大众审美的美女(wallpaper);
另外还必须具有良好的交互性,没有良好的交互性就像你对一位美女殷勤了半天,她却直接对无视,那结果是比较糟糕的~~
所谓兵马未动,粮草先行,在了解launcher的细节之前,我们首先需要完成对一些知识的扫盲。
当然这些知识我们都可以在SDK guide大叔那边找到,俺可以很负责任地告诉大家,如果你把SDK guide大叔的三板斧都学会了,
APK你基本就处于无敌状态了,绝对护甲+10000,最起码基础知识是够了,其他比的就是创意了:


1、必须比较完整地了解APK的4个部件,尤其是Activity,现在可以简单地理解Activity是一个应用程序的窗口。


2、必须了解UI的那部分内容,这部分内容是比较多的,English一般的我看得是比较抑郁的,但如果你想设计一个符合自己审美要求的美女或者帅哥是必须得得了解的,
不需要一下能完全理解,但至少出了问题你知道去哪部分查~~


3、Resources那部分内容可以当百科全书查


4、intent那部分内容也是需要了解比较详细的,他是和应用沟通的渠道,大家可以参考一下小斯大虾写的文档。


5、manifest必须了解,security可以看看


6、Graphic部分的内容是给需要更高品味的GUI设计提供的,虽然它可能主要用在游戏上面,但我觉得如果要作出够酷的GUI肯定是需要2d,3d引擎的。


7、AppWidget可以作为了解,用的时候再翻阅




各位路过的大虾们肯定被这么多的粮草给直接雷倒了,其实需要我们详细掌握的是1和2,其他的都可以当作百科全书,但是如果能仔细地看透了那是最好了。
好,万事俱备只欠东风了,我们首先来看看这个Home是在啥时候由谁来启动的。这部分知识可以跳过,但是理解一下是好的,
你可以了解一个APK进程是如何怀胎十月之后诞生的。可能下面说到的词汇有些生涩,所以建议先看看Android Anatomy and Physiology.pdf。
Linux kernel启动以后会通过App_main进程来初始化android Runtime Java运行环境,而zygote是android的第一个进程。
所有的android的应用以及大部分系统服务都是通过zygote fork出来的子进程(我现在看到的只有native的service manager不是由zygote fork出来的)。
在system server中启动的若干系统服务中与我们启动进程相关的就是Acitivity Manager。
当systerm server启动好所有服务以后,系统就进入”system ready”状态,这个时候Activity Manager就登场了。
Activity Manager光看代码行就知道是一个重量级的服务,它主要管理Activity之间的跳转,以及进程的生命周期。
当Activity Manager发现系统已经启动好以后它就会发出一个intent:
Intent intent = new Intent(
mTopAction,
mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}


通过这个category类型为home的intent,Activity Manager就会通过:
startActivityLocked(null, intent, null, null, 0, aInfo,
null, null, 0, 0, 0, false, false);


启动Home进程了。而这个启动Home进程的过程实际上还是去通过zygote fork出的一个子进程。


因此只要在manifest中具备这样的intent-filter都可以在开机的时候作为Home启动:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>


多个home之间的switch会在开始的时候有个选择,至于这个选择好像是package manager来实现的,没有仔细研究过。




好啦,了解了Lancher是如何执行的,我们再来看看整个lancher内部构造。看看一个lancher如何构造才算是个长得对得起观众的娃:
1、取得系统中所有安装好的应用程序,并提供能运行这些程序的映射(形象的理解就是一个一个应用程序的小图标)。这是Lancher的骨架,
正所谓何谓lancher是吧~~如果它不能提供应用程序的访问,再好看也至多是一个华丽的花瓶而已,啥用米有。
2、更好一点我们就需要为这个设计良好的骨架提供一些画皮以及一系列动画效果,就是我们的wallpaper以及一系列的图像,
animation,graphic之类的。如果完成这部分工作,基本上我们的Home就基本成型了。
3、要使得我们的GUI更具亲和性更方便使用,我们还提供一些额外的功能,比如说现在lancher实现的图标的拖动,快捷方式等等。
这些都是仁者见仁智者见智的事情,取决你天马行空的设计了。


总结起来一个lancher包含3个部分内容:应用程序信息采集,事件处理,动画。下面我们来讲述一个自己的launcher的实现过程:
1、设计
从纯用户的角度来设计你的界面,你希望达到什么样的效果,尽量写得详细。尤其是应用程序信息以如何方式的出现,
以及对它的操作一般都是一个好设计的亮点。我们现在设计一个简单的,我们需要一个墙纸,然后在这个墙纸上面有一个条形的控件来显示我们的应用程序图标。
选择这些图标以后会在屏幕中间出现一张图表示这个应用程序的功能,然后单击这个图就会打开这个应用程序。
2、设计的总体实现
针对自己的设想来设计这个lancher的整体实现,如果有无法实现的内容就要及时修改设计,或者换一种设计方案。
我们这里使用一个 FrameLayout来作为我们的Lancher的容器。然后分层,最下面一层用来放置可能需要的快捷方式以及我们的 wallpaper,
然后在wallpaper层上放一个我们自己定义的component来显示我们的应用程序信息。个人觉得FrameLayout是比较适合作为lancher的layout的,
它类似于photoshop的图层这样的控制,上面的图层会覆盖下面的图层。
3、具体功能的具体实现
这里具体到代码上就是设计各种java功能类了。对于wallpaper和图标的拖拽移动这里简单提一下,更多的可以去看Android Lancher的实现。
wallpaper一般是注册一个broadcastreceiver来处理系统中所有的更改背景图片的请求,而图标的脱拽移动则涉及到Draglayer这个类。
我们来把重点放在如何取得Android已安装的应用程序信息上。这里就涉及到我们另外一个重要的service了,它就是package manager,
它负责对安装的包进行管理。这里涉及到一些权限,我是直接照着android lancher的实现把它的权限拷贝过来的:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />


下面来看看具体的实现,我们创建一个自己的控件,使用LinearLayout来装载ImageSwitcher和Gallery两个控件,
用 Gallery来显示获得的应用程序信息,用ImageSwitcher来显示应用程序的介绍,单击ImageSwitcher就能打开相应的应用程序。
public class MyLancherSwitcher extends LinearLayout implements ViewSwitcher.ViewFactory, AdapterView.OnItemSelectedListener,AdapterView.OnItemClickListener{
mImageSwitcher = new ImageSwitcher(context) ;
mGallery = new Gallery(context) ;
this.addView(mImageSwitcher, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,400)) ;
this.addView(mGallery, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 80)) ;



架构选好了,下面就是如何为这个两个控件提供已安装的应用程序的信息,首先我们取得package manager :
PackageManager manager = this.getContext().getPackageManager();


然后package manager通过intent信息来提供相应的应用程序信息:
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List <ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
Collections.sort(apps, new ResolveInfo.DisplayNameComparator(manager));


然后我们定义个自己的类MyAppInfo来存储这些取得的信息:
for (int i = 0; i < count; i++) {
MyAppInfo application = new MyAppInfo();
ResolveInfo info = apps.get(i);
application.title = info.loadLabel(manager);
application.setActivity(new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name),
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
application.icon = info.activityInfo.loadIcon(manager);
mApplications.add(application);
}
final void setActivity(ComponentName className, int launchFlags) {
intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(className);
intent.setFlags(launchFlags);
}


我们使用一个数组来存储这些MyAppInfo信息,并把它提供给Gallery:
private static ArrayList <MyAppInfo> mApplications;
mGallery.setAdapter(new ApplicationsAdapter(this.getContext(), mApplications)) ;


最后重载ArrayAdapter <MyAppInfo>的getView()函数对画图进行一些裁减就OK了,Gallery就能显示我们的应用程序的图片信息了。
最后我们把Gallery中被选中的图片的应用程序信息传给ImageSwitcher,并为ImageSwithcher注册一个按键事件,就可以启动应用程序了:
private OnClickListener mImageSwitcherListener = new OnClickListener(){
public void onClick(View v){
if(mAppInfo == null){}
else
v.getContext().startActivity(mAppInfo.intent);
}
} ;


这样基本我们lancher的骨架就搞定了,不过还有一个,那就是当我们新安装或删除一个应用程序的时候,我们的Home必须捕获这个intent,
并及时调整home里面的应用程序信息,因此我要为我们的控件注册一个package的broadcast receiver :
private class ApplicationsIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
loadApplications(false);
}
}


private void registerIntentReceivers() {
filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
registerReceiver(mApplicationsReceiver, filter);
}

Ok这样我们的lancher就基本完成了,剩下的就是为各个事件添加你需要的动画效果,这里就不说了。以前没有经历过java编程,
但是个人觉得 android java应用的编程还是相对简单的,只是因为东西很多所以显得有点复杂,但是基本上使用起来还是很方便的,
基本就是继承之后重载或者实现接口,而且 Android为Ui的编程提供了一个更方便的方式就是使用XML,使用xml可以更直观地来进行你的设计,
而且也方便了你以后的修改和移植。




分享到:
评论

相关推荐

    Android11.0 Launcher3 添加负一屏(谷歌Feed屏方案)

    包含服务端 OverlayScreen(可替换成你自己客需定制负一屏View) 基于android11.0 绝对好用,网上目前最全代码 实现效果图 &lt;img src="https://i.postimg.cc/g2phQy6y/Screen.gif" border="0" /&gt;

    新版Android开发教程.rar

    也有分析认为,谷歌并不想做一个简单的手机终端制造商或者软件平台开发商,而意在一统传统互联网和 移 动互联网。----------------------------------- Android 编程基础 4 Android Android Android Android 手机新...

    全球任性的安卓手机桌面软件 TSF Launcher 3.9.4 中文直装免费版.zip

    你能够非常自由,高效地自定义你桌面的每 一个元素.TSF SHELL不断推出的新功能与专属3D小部件将会给你带来震撼,出色的操作体验与视觉享受。 全球最任性的安卓手机桌面软件 TSF Launcher 中文版全球最任性的安卓手机...

    安卓 GO 桌面 GO Launcher 3.30 中文免费版.zip

    其早期版本“ GO Launcher EX”在Google Play中排名第一,拥有超过2亿用户! GO 桌面增强版 GO Launcher 中文多语免费版GO 桌面增强版 GO Launcher 中文多语免费版 软件名称:GO桌面版:GO Launcher 软件版本:...

    android开发资料大全

    从零开始Android游戏编程(第二版) 新版Android开发教程&笔记(1-12) eoeAndroid社区精华特刊共24期全部原创 《深入浅出Android--Google手持设备应用程序设计》下载 《Android编程指南》android-book.pdf 下载 ...

    Android7.0开发实现Launcher3去掉应用抽屉的方法详解

    年初做过一个项目,有一个需求就是需要将桌面变为单层不需要二级菜单。最近几次有小伙伴有这个问我这个解决办法。现在我将分享给大家。 先上效果图:   功能分解 1. 去除Allapp键,调整HotSeat布局 2. 将所有应用摆...

    Google Android SDK开发范例大全(完整版)

    该目录包含将开发环境连接到支持 Android 的设备(例如 G1 或 Android Dev 1 解锁开发手机)所需的驱动程序。只有 Windows 平台的开发人员才需要这些文件。 Android 应用程序可以在实际的设备上运行,也可以在 ...

    Google Android SDK开发范例大全(第3版) 1/5

    全书共分11章,主要以范例集的方式来讲述Android的知识点,详细介绍了开发Android的人机交互界面、Android常用的开发控件、Android手机收发短信等通信服务、开发Android手机的自动服务功能和娱乐多媒体功能以及整合...

    Google Android SDK开发范例大全(第3版) 4/5

    全书共分11章,主要以范例集的方式来讲述Android的知识点,详细介绍了开发Android的人机交互界面、Android常用的开发控件、Android手机收发短信等通信服务、开发Android手机的自动服务功能和娱乐多媒体功能以及整合...

    Google Android SDK开发范例大全(第3版) 3/5

    全书共分11章,主要以范例集的方式来讲述Android的知识点,详细介绍了开发Android的人机交互界面、Android常用的开发控件、Android手机收发短信等通信服务、开发Android手机的自动服务功能和娱乐多媒体功能以及整合...

    Google Android SDK开发范例大全(第3版) 5/5

    全书共分11章,主要以范例集的方式来讲述Android的知识点,详细介绍了开发Android的人机交互界面、Android常用的开发控件、Android手机收发短信等通信服务、开发Android手机的自动服务功能和娱乐多媒体功能以及整合...

    Google Android SDK开发范例大全(第3版)part2

     全书共分11章,主要以范例集的方式来讲述Android的知识点,详细介绍了开发Android的人机交互界面、Android常用的开发控件、Android手机收发短信等通信服务、开发Android手机的自动服务功能和娱乐多媒体功能以及...

    《Google Android SDK开发范例大全(第3版)》.pdf

     全书共分11章,主要以范例集的方式来讲述android的知识点,详细介绍了开发android的人机交互界面、android常用的开发控件、android手机收发短信等通信服务、开发android手机的自动服务功能和娱乐多媒体功能以及...

    CustomLauncher3:自己修改的安卓系统桌面,基于Launcher3

    关于自己修改的安卓系统桌面,基于Launcher3源码。链接 调整###解决不能安装的问题解决可能因为相同权限声明或内容提供者冲突而不能安装的问题,需要插入包称为非com.android.launcher3,并放置所有...

    android开发使用例子

    在进行Android开发的过程中,免不了,要开发TCP/UDP通讯的程序,下面这两段代码,分别介绍了TCP/UCP通过的一个实例: 代码一: private void tcpdata() { try { Socket s = new Socket("192.168.0.25", 65500); ...

    疯狂Android讲义源码

     第2章 Android应用的界面编程 35  2.1 界面编程与视图(View)组件 36  2.1.1 视图组件与容器组件 36  2.1.2 使用XML布局文件控制UI  界面 40  2.1.3 在代码中控制UI界面 41  2.1.4 使用XML布局文件和Java ...

    Pixelful_Icon_Pack_Pro_v7.1.apk

    受第一个也是唯一一个图标包的深色版本,其灵感来自于新的Pixel设备样式,旨在转变设备的图形。 重要说明 •这是一个图标包,需要自定义启动器才能工作。Google Now Launcher,Pixel Launcher或工厂安装的任何...

    疯狂Android讲义.part2

    第2章 Android应用的界面编程 35 2.1 界面编程与视图(View)组件 36 2.1.1 视图组件与容器组件 36 2.1.2 使用XML布局文件控制UI 界面 40 2.1.3 在代码中控制UI界面 41 2.1.4 使用XML布局文件和Java 代码混合控制UI...

    疯狂Android讲义.part1

    第2章 Android应用的界面编程 35 2.1 界面编程与视图(View)组件 36 2.1.1 视图组件与容器组件 36 2.1.2 使用XML布局文件控制UI 界面 40 2.1.3 在代码中控制UI界面 41 2.1.4 使用XML布局文件和Java 代码混合控制UI...

Global site tag (gtag.js) - Google Analytics