androidlauncher源码
Ⅰ 有没有人分享一下修改launcher的历程
我自己总结的,ubuntu和windows下几种不同的修改Launcher的方法:
总共有三大类:
#################
第一类,改签名:
#################
前面几个步骤ubuntu和windows通用:
=====================================================================================================
1 eclipse中新建android project,选择create project from existing source,去android源码目录下的packages/apps下找到相应的文件夹。(直接修改的是源码,所以需要先打包备份一下)然后选择build target之后finish,可能会等待一段时间。
2 导入完成后,src全是错误,由于在Android源码中,很多方法、成员、类、包都被打上@hide标签,这些成员在SDK中没有公开,以至于在编译Launcher源码时最常遇到的类android.view.View的成员mScrollX无法访问。
。以Launcher2为例,我们用到的有:(生成的包的路径为out/target/common/obj/java_LIBRARIES)
1)framework_intermediates/classes.jar :这个主要是android的框架类
2)android-common_intermediates/classes.jar :这个包含com.android.common.Search这个类
3)core_intermediates/classes.jar :这个包包含dalvik.system.VMRuntime这个类
右键工程名称然后选择Build Path->Configure Build Path...->Libraries->Add Library->User Library->User Libraries...->New...
然后将上面3个依赖的包一个个的加入进来,分别命名为android_framework,android_common,android_core.
将3个包加入进来后,然后还需要将它们放到android2.3.3这个包的前面,可以在Build Path配置中选择Order and Export
这时候就会发现Launcher2工程以及没有错误了,也可以编译了。(其他的模块可能需要别的jar包,都在out/target/common/obj/JAVA_LIBRARIES下能找到).
=====================================================================================================
然后:
===================================================================================================
windows环境下:工程现在是不能直接运行的,因为eclipse默认的debug签名跟模拟器中的系统签名不相符合。因此,因此,需要手动签名。
3 用eclipse导出没有签名的版本,右键工程,android tools->export unsigned application package,得到未签名的apk包。
4 在build\target\proct\security下都是一些公钥和密钥,system版本的公钥和密钥是platform.pk8和platform.x509.pem两个文件,shared版本的公钥和密钥是shared.pk8和shared.x509.pem两个文件。模块应用是什么版本的可以查看AndroidManifest.xml文件,android:sharedUserId="android.uid.system" 表示是system版android:sharedUserId="android.uid.shared"是shared版。除了公钥密钥之外,还需要签名的包即signapk.jar,它在out/host/linux-x86/framework下。
5 将这些工具准备好后,就能打出签名包了。比如我的为签名apk是Launcher.apk并且是shared版本。因此java -jar signapk.jar share.x509.pem shared.pk8 Launcher.apk Launcher-signed.apk(system版本就用platform.pk8和platform.x509.pem相应的替换一下)
6 得到了签名包之后,adb install -r Lancher-signed.apk就行了,直接替换掉原来的Launcher。
=====================================================================================================
ubuntu环境下:利用android源码提供的工具自动签名
3 编译源码
4 gedit .bashrc 最后面添加
export PATH=$PATH:/home/xxx/android/out/host/linux-x86/bin
export ANDROID_PRODUCT_OUT=/home/xxx/android/out/target/proct/generic
其中的/home/xxx/android是源码目录
5 然后启动模拟器,命令为emulator
6 在eclipse中修改好源码模块比如Launcher2之后,将工程放到android源码目录下的packages/apps下,删除掉自动生成的一些文件,比如bin,assets,gen等等。跟其他模块文件保持一致。
7 android源码目录下执行 . build/envsetup.sh 这个时候多出mm,mmm等命令,进入修改过后的那个模块目录下,比如packages/apps/Launcher2/下,执行mm,会自动生成已经签名过的apk文件,放在out/target/proct/generic/system/app下。
8直接adb install -r out/target/proct/generic/system/app/Launcher2.apk即可。
=====================================================================================================
注意:以上的签名跟源码相关,如果源码只是generic的也就是模拟器版,那么编译出来的也只能在模拟器上跑,若要在真机上跑,则需要真机的签名库,可惜没有- -,所以需要:
##################
第二类,改包名。
##################
照常理说,应该很简单,直接在src下的包上F2,然后修改。但是我的机器这个eclipse很奇怪,总有各种问题,现在总结下:
1.导入工程,备份一下AndroidManifest.xml,原因下面有。F2修改包名,修改的时候下面四个选项都选上。
2.修改AndroidManifest.xml
将备份的AndroidManifest.xml换回来,然后ctrl+f,替换全部的原来包名为你现在的,比如之前是com.android.launcher2,现在换成com.pqrs.launcherEx。然后将android:sharedUserId="XXX"这句话删掉。(这么做的原因是,在第一步中可能已经自动的替换了一些这个xml文件的东西,但是我这eclipse乱七八糟的,缺字或者其他什么的,此时文件已经损坏了。所以第一步之前,需要备份一下AndroidManifest.xml,在这个步骤中替换回来,然后ctrl+f进行替换。)
3.保存后会有提示,说这个文件变化了,是否作出其他变更,点击yes。然后res下可能会有一些错误,打开那些xml文件,一般都是有些资源引用还是之前的com.android.launcher2,相应的都该成com.pqrs.launcherEx.
比如<favorites xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher2">改为<favorites xmlns:launcher="http://schemas.android.com/apk/res/com.pqrs.launcherEx">
4.由于AndroidManifest.xml中的包名改了,gen目录下的自动生成文件也会跟着变化,但是src下的java文件引用的R文件路径还没便过来,还需要更正过来。方法:包名上ctrl+h,选择file search,在Containing text下输入之前的import语句,比如是import com.android.launcher2.R;在File name patterns:中填入*.java(表示搜索java文件)scope下选择Selected resources,然后点击Replace进行全局替换。
5.如果都顺利的话,现在这就是一个新的工程了,直接在eclipse中修改运行即可,而且不限操作系统。
====================================================================================================
#############################################
第三类,网上流传的,最传统的方法,只限于ubuntu下。
##############################################
1、建立基本的Android开发环境
请参考官方文档或<<Android模拟器在Ubuntu8.10的安装>>
2、编译Android源码
Android源码根目录下通过make进行编译,请注意一些配置,具体可参考<<android源码的编译>>
3、把eclipse工程配置文件复制到Android源码根目录下
cp development/ide/eclipse/.classpath ./
chmod u+w .classpath # Make the writable
4、修改eclipse程序的配置
1)、增大eclipse内存设置
把eclipse.ini(在eclipse软件的安装目录下)的3个值改为下面的值:
-Xms128m
-Xmx512m
-XX:MaxPermSize=256m
2)、把Android-formatting.xml和android.importorder导入eclipse(可选)
Android-formatting.xml、.classpath和android.importorder都放在development/ide/eclipse/下
Android-formatting.xml用来配置eclipse编辑器的代码风格;android.importorder用来配置eclipse的import的顺序和结构。
在window->preferences->java->Code style->Formatter中导入Android-formatting.xml
在window->preferences->java->Code style->Organize Imports中导入Android.importorder
3)、安装anyedit插件(可选)
在http://andrei.gmxhome.de/anyedit/下载并导入eclipse中
5、把Android源码作为一个工程导入eclipse
导入前先检查.classpath里的文件在Android源码中是否有相应的文件(文件夹),否则也会破坏android源码(一般是多添加文件/文件夹),.classpath里多余的路径可删除
新建Java Project(不是Android project,否则会破坏android源码),www.linuxidc.com选择从已存在的工程导入,工程名任意,完成。
导入时,eclipse要build工程,比较慢。导完后,一般都没有错误。
这里也就回答了第4个问题
6、eclipse上调试Android里的程序。
为了不让其它版本的Android工具和android文件系统影响下面的编译和调试,需要从环境变量中去除android工具和android文件系统的路径:
vim ~/.bashrc
看看有没有在PATH变量中加入Android工具和android文件系统的路径,如果加有,则注释它。通过下面的方法,我们是不需要在.bashrc中添加android工具和android文件系统的路径的
执行:
cd Android源码目录
. build/envsetup.sh #设了环境变量之后,会多出mmm等命令,可以通过输入help来查看
lunch 1 # 把emulator等工具和ramdisk.img等文件的路径对应起来,就可以直接调用emulator等工具,也解决了第3个问题
emulator &
ddms &
注意,先启动ddms,再启动eclipse,这样eclipse中就不会说端口冲突
然后在eclipse中配置调试类型和端口:
在Run->Debug Configurations->Remote java application上双击,然后,”Host:”设为localhost,”Port:”设为8800,”Connection Type”为Standard(Socket Attach)
然后“Apply”
注意,上面设置的端口要与DDMS中设置的端口一致,ADT插件使用了8700端口,因此上面设置的端口是8800。如果出现连不到VM的错误时,请注意,要先在DDMS中选中某一进程(对应某一应用程序),才能在eclipse执行 Debug。
在eclipse调试时,可以设断点、单步调试。估计google团队也是这样开发、调试Android应用程序的
7、编译Android源码
执行:
cd Android源码目录
. build/envsetup.sh
那 么就会多出mm/mmm等命令,mm/mmm用来编译模块(包括C、C++、JAVA程序)。我们也可以直接在 Android源码根目录下执行“make 模块名”来编译模块(模块名可以在.mk文件中找到)。模块编译后会在out/target/proct/generic/system/app下生 成对应的.apk包。但是,用mm/mmm来编译生成的.apk并不会打包到system.img中,需要我们手动通过make snod把 system文件夹打包为system.img,不过这就得重新运行模拟器了,这也是很麻烦了。对于我们开发者来说,我们可以这样做:
1)把需要修改、调试的模块(比如AlarmClock.apk)从/system/app下移除,然后make snod,这样system.img就没有AlarmClock.apk了。
2)运行模拟器,就看不到AlarmClock了
3)修改AlarmClock源码并用mm/mmm来编译,在/system/app下生成AlarmClock.apk
4)通过adb把AlarmClock.apk安装到Android文件系统中,安装方法有两个:
A、通过adb install xxx/AlarmClock.apk
B、通过adb push xxx/AlarmClock.apk /data/app
两 种方法都可以把 AlarmClock安装到/data/app下,Android会自动把它显示在主菜单中(只要AlarmClock.apk中有一Activity包 含android.intent.category.LAUNCHER属性),不过A方法在/data/app生成 com.android.alarmclock.apk,B方法则是 AlarmClock.apk。用A方法时,如果原来已经安装了 AlarmClock,你还得先adb uninstall 它,而B方法则不用。推荐使用B方法。同样,卸载可以通过adb uninstall或adb shell rm xxx/xxx.apk来,也推荐用删除的方法来卸载
Ⅱ android launcher源码怎么用
在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应用程序就是Launcher了,本文将详细分析Launcher应用程序的启动过程。
Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而ActivityManagerService和PackageManagerService一样,都是在开机时由SystemServer组件启动的,SystemServer组件首先是启动ePackageManagerServic,由它来负责安装系统的应用程序,具体可以参考前面一篇文章Android应用程序安装过程源代码分析,系统中的应用程序安装好了以后,SystemServer组件接下来就要通过ActivityManagerService来启动Home应用程序Launcher了,Launcher在启动的时候便会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上,这样用户就可以使用这些应用程序
Ⅲ Android源码环境编译出来的apk 怎么安装到手机上去
如果手机上已经有包名一样的apk是安装不上去的吧,如果可以用adb remount 再push到system/app替换原来的launcher试试
Ⅳ Android的Launcher3源码中,FocusIndicatorView有什么作用
1、Launcher进程启动过程可以由下面图看到Launcher进程是如何被创建启动:ActivityManager通过发送Intend来启动Launcher。Intentintent=newIntent(mTopAction,mTopData!=null?Uri.parse(mTopData):null);intent.setComponent(mTopComponent);if(mFactoryTest!=SystemServer.FACTORY_TEST_LOW_LEVEL){intent.addCategory(Intent.CATEGORY_HOME);}startActivityLocked(null,intent,null,null,0,aInfo,null,null,0,0,0,false,false);复制代码因此,如果你要开机启动一个替换Launcher的程序,只要在程序里面加入action.MAIN、category.HOME、category.DEFAULT就可以。如果出现多个程序都加入这种intent,系统会弹出让你选择哪个作为启动器。2、Launcher初始化——LauncherApplication。Application类,我想大部分做Android应用的朋友都用过,每个Android应用默认都有一个Application类,你也可以继承Application类,然后加入自己代码。Application是一个全局的应用类,在AndroidManifest.xml我们也可以找到Application标签。复制代码Android四大组件的声明都需要放到application标签里面,默认使用的是系统的Application类,如果你在项目里面重载了它。就需要在标签,name属性下写上你的新的Application类名。Launcher里面就是继承了Application为LauncherApplication。应用启动的时候首先会加载Application。我们可以看到Launcher主类Launcher.java的onCreate函数里面,第一个就是获取Application的实例。LauncherApplicationapp=((LauncherApplication)getApplication());复制代码接下来我们看看LauncherApplication里面初始化,LauncherApplication大部分工作就是在初始化完成,剩下都是一些返回接口。@OverridepublicvoidonCreate(){super.onCreate();//获取屏幕大小,主要用来区分手机还是平板finalintscreenSize=getResources().getConfiguration().screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK;sIsScreenLarge=screenSize==Configuration.SCREENLAYOUT_SIZE_LARGE||screenSize==Configuration.SCREENLAYOUT_SIZE_XLARGE;//屏幕密度sScreenDensity=getResources().getDisplayMetrics().density;//IconCahe里面保存了界面所有应用图标的绘画需要的数据,这个到时候具体分析再说。//加入这东西的主要原因是为了提高绘画界面的效率mIconCache=newIconCache(this);//数据库加载类,LauncherModel是Launcher里面非常重要的一个类,相当于MVC模式里面的//Model功能,管理数据和初始化数据mModel=newLauncherModel(this,mIconCache);//下面注册了一些监听器,主要包含APK文件更新删除等数据变化的时候接收的通知//接收通知后,主要是用来更新Launcher里面的数据库。因为桌面应用图标数据,只会加载一次IntentFilterfilter=newIntentFilter(Intent.ACTION_PACKAGE_ADDED);filter.addAction(Intent.ACTION_PACKAGE_REMOVED);filter.addAction(Intent.ACTION_PACKAGE_CHANGED);filter.addDataScheme("package");registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);filter.addAction(Intent.ACTION_LOCALE_CHANGED);filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);registerReceiver(mModel,filter);//contentresolver则是用于管理所有程序的contentprovider实例ContentResolverresolver=getContentResolver();//注册内容观察者,监听application数据库变化,回调resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI,true,mFavoritesObserver);}复制代码上面是LauncherApplication最主要的工作,初始化整个Launcher的一些关键类,和注册一些监听器。主要都是用来监听应用的安装更新删除等导致Launcher数据库变化的操作。Launcher数据都是使用contentprovider来提供数据。其中注册的监听接口是=newContentObserver(newHandler()){@OverridepublicvoidonChange(booleanselfChange){//重新加载界面数据mModel.startLoader(LauncherApplication.this,false);}};复制代码LauncherSettings.Favorites.CONTENT_URI里面数据发生变化的时候,都会调用mModel.startLoader()接口,重新加载Launcher的数据。startLoader的具体操作,我后面分析LauncherModel类的时候会分析。这一块涉及Launcher所有数据加载。剩下的接都是返回初始化时候创建的对象或者获取屏幕密度、获取是否大屏幕。后面很多处理都需要判断是否是大屏幕,4.0以后手机平板都共用一套系统,导致多了很多处理。3、Launcher.java初始化Launcher.java是Launcher里面最主要的类,是一个Activity。启动的第一个组件。既然是Activity,我们要分析它初始化,毫无疑问,需要找到onCreate()里面分析。把主要一些分析用注释方式写在代码里面,这样比较方便阅读。
Ⅳ android Launcher的滑动效果怎么实现
滑动功能主要分两步:
1、在onInterceptTouchEvent中进行拦截。
2、在onTouchEvent中进行滑动。
1,onInterceptTouchEvent(MotionEvent en)
在这个方法中,决定了什么时候截获MotionEvent来实现滑动,避免了子View的其他事件的影响(如点击事件)。
[java] view plain
public boolean onInterceptTouchEvent(MotionEvent ev) {
/**
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
* scrolling there.
**/
//获取速度跟踪器,记录各个时刻的速度。并且添加当前的MotionEvent以记录更行速度值。
(ev);
......
/**
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
* 最常见的需要拦截的情况:用户已经进入滑动状态,并且正在滑动手指。
* 对这种情况直接进行拦截,执行onTouchEvent()继续执行滑动操作。
**/
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) &&
(mTouchState == TOUCH_STATE_SCROLLING)) {
return true;
}
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {
/**
* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
* whether the user has moved far enough from his original down touch.
*/
/**
* 当在这里接受到ACTION_MOVE时,说明mTouchState!=TOUCH_STATE_SCROLLING并且mIsBeingDragged的值应该为false,
* 否则DragLayer就应该截获了MotionEvent用于实现拖拽。
* 此时还没有进入滑动状态,当mActivePointerId == INVALID_POINTER时,也就是在此之前没有接收到任何touch事件。
* 这种情况发生在Workspace变小时,也就是之前Workspace处于SPRING_LOADED状态。当出现这种情况时直接把当前的事件当作ACTION_DOWN进行处理。
* 反之,则通过determineScrollingStart()尝试能够进入滑动状态。
*/
if (mActivePointerId != INVALID_POINTER) {
determineScrollingStart(ev);
break;
}
// if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
// event. in that case, treat the first occurence of a move event as a ACTION_DOWN
// i.e. fall through to the next case (don't break)
// (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events
// while it's small- this was causing a crash before we checked for INVALID_POINTER)
}
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
// Remember location of down touch
//记录按下的x的坐标值
mDownMotionX = x;
//记录前次发生touch时的坐标
mLastMotionX = x;
mLastMotionY = y;
//因为在ScrollBy时只能使用int,而记录的x和y都是float,会产生误差,故这里用mLastMotionXRemainder记录余数
//用于消除误差
mLastMotionXRemainder = 0;
//x方向上的总位移
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
//设置mAllowLongPress=true,允许LongClick事件发生。LongClick事件定义在Launcher中
//处理的内容包括启动对shortcut的拖拽或弹出壁纸选择的对话框,若mAllowLongPress=false,
//则不会响应以上事件。
mAllowLongPress = true;
/**
* If being flinged and user touches the screen, initiate drag;
* otherwise don't. mScroller.isFinished should be false when
* being flinged.
* 当屏幕处于flinged状态(快速滑动)时,若此时用户触摸了屏幕,需要使滑动停止。
* 并且初始化拖拽的条件
**/
final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
if (finishedScrolling) {
mTouchState = TOUCH_STATE_REST;
mScroller.abortAnimation();
} else {
mTouchState = TOUCH_STATE_SCROLLING;
}
// check if this can be the beginning of a tap on the side of the pages
// to scroll the current page
if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
if (getChildCount() > 0) {
if (hitsPreviousPage(x, y)) {
mTouchState = TOUCH_STATE_PREV_PAGE;
} else if (hitsNextPage(x, y)) {
mTouchState = TOUCH_STATE_NEXT_PAGE;
}
}
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
mAllowLongPress = false;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
releaseVelocityTracker();
break;
}
/**
* The only time we want to intercept motion events is if we are in the
* drag mode.
* 只有进入了滑动状态,才进行拦截,进入onTouchEvent执行滑动操作。当mTouchState != TOUCH_STATE_REST
* 时,就说明没有进入滑动状态。
**/
return mTouchState != TOUCH_STATE_REST;
}
2,onTouchEvent(MotionEvent en)
在这个方法中,执行各种关于滑动的工作的计算,界面的刷新等工作。
[java] view plain
public boolean onTouchEvent(MotionEvent ev) {
......
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
/**
* 如果Workspace此时已经被“掷出去”(靠惯性滑动)。
* 此时发生ACTION_DOWN则需要停止滑动。
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
// Remember where the motion event started
mDownMotionX = mLastMotionX = ev.getX();
mLastMotionXRemainder = 0;
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
if (mTouchState == TOUCH_STATE_SCROLLING) {
pageBeginMoving();
}
break;
case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
if (Math.abs(deltaX) >= 1.0f) {
......
if (!mDeferScrollUpdate) {
//调用scrollBy滑动桌面
scrollBy((int) deltaX, 0);
......
} else {
......
}
mLastMotionX = x;
mLastMotionXRemainder = deltaX - (int) deltaX;
} else {
awakenScrollBars();
}
} else {
/**
* 如果条件满足,则进入滑动状态,开始滑动。
*/
determineScrollingStart(ev);
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
boolean isSignificantMove = Math.abs(deltaX) > MIN_LENGTH_FOR_MOVE;
boolean returnToOriginalPage = false;
final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
Math.signum(velocityX) != Math.signum(deltaX)) {
returnToOriginalPage = true;
}
boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
Math.abs(velocityX) > snapVelocity;
int finalPage;
//判断拿起手指之后应该进入哪个分屏
if (((isSignificantMove && deltaX > 0 && !isFling) ||
(isFling && velocityX > 0)) && mCurrentPage > 0) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
snapToPageWithVelocity(finalPage, velocityX);
} else if (((isSignificantMove && deltaX < 0 && !isFling) ||
(isFling && velocityX < 0)) &&
mCurrentPage < getChildCount() - 1) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
snapToPageWithVelocity(finalPage, velocityX);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
//直接进入前一屏
int nextPage = Math.max(0, mCurrentPage - 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
//直接进入后一屏
int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else {
onUnhandledTap(ev);
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_CANCEL:
if (mTouchState == TOUCH_STATE_SCROLLING) {
snapToDestination();
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}
Ⅵ 怎样查看 Android APP 源代码
用压缩软件打开apk文件,解压出根目录中的classes.dex文件
使用cmd ,dex2jar.bat classes.dex命令将classes.dex转换为jar
再用jd-gui打开该jar就可以查看源码了,如果apk安全性好的话,有些代码是看不到的
Ⅶ Android4.0 怎么在launcher2 源码中添加快捷键
萨斯
Ⅷ 如何编译android launcher
注意前提条件是具备下面事项,需要系统级别的权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rtkj.switchlauncher"
android:sharedUserId="android.uid.systemui"
<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
可以导出Apk文件放到系统的system/app目录下面去编译
第一种方式 : 清理Launcher的默认设置的 默认值相当于在设置->应用程序->管理应用程序->所有应用程序列表,找到之前设置的
默认Launcher,并取消了默认值,系统会重新弹出launcher选择框。
private void clearDefaultValues(String packageName) {
getPackageManager().(packageName);
}
第二种方式: 通过pm进行 清理 后添加 或者是替换当前的 ,这里显示的是两个Launcher的替换
view plain
private void setDefaultHome(String packeageName ,String className,String oldPackage,String oldName) {
PackageManager pm = getPackageManager();
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_MAIN);
f.addCategory(Intent.CATEGORY_HOME);
f.addCategory(Intent.CATEGORY_DEFAULT);
ComponentName component = new ComponentName(packeageName,className );
ComponentName[] components = new ComponentName[] {new ComponentName(oldPackage,oldName),component};
<span style="color:#FF0000;">pm.(oldPackage);</span>// 清理配置的默认信息
pm.addPreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, components, component);//添加
<span style="color:#FF0000;">//pm.replacePreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, components, component);</span> //替换
}
view plain
//存在多个以上的Launcher的时候
private void setDefaultLauncher() {
// remove this activity from the package manager.
PackageManager pm = getPackageManager();
String examplePackageName = "com.jeejen.family"; //请修改为需要设置的 package name
String exampleActivityName = "com.jeejen.home.launcher.Launcher"; //请修改为需要设置的 launcher activity name
ComponentName defaultLauncher = null;
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> resolveInfoList =
pm.queryIntentActivities(intent, 0);
if (resolveInfoList != null) {
int size = resolveInfoList.size();
for (int j = 0; j < size; ) {
final ResolveInfo r = resolveInfoList.get(j);
if (!r.activityInfo.packageName.equals(examplePackageName)) {
resolveInfoList.remove(j);
size -= 1;
} else {
j++;
}
}
ComponentName[] set = new ComponentName[size];
defaultLauncher = new ComponentName(examplePackageName, exampleActivityName);
int defaultMatch = 0;
for (int i = 0; i < size; i++) {
final ResolveInfo resolveInfo =
resolveInfoList.get(i);
set[i] = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
if (defaultLauncher.getClassName().equals(resolveInfo.activityInfo.name)) {
defaultMatch = resolveInfo.match;
}
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);
pm.(defaultLauncher.getPackageName());
pm.addPreferredActivity(filter, defaultMatch, set, defaultLauncher);
}
}
切换后启动当前的Launcher,
view plain
public void startMainLauncher(){
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}
Ⅸ 请教关于make/编译android源码中的Launcher2出现错误/error41
其实这个问题我也遇到了,不过楼上的方法虽然能解决问题,但是各位有木有相关想过一个问题:每次都要删除不闲麻烦吗?为什么packages/apps/下面的应用我们导入到Eclipse里,一样的生成了R.java文件,为什么能够顺利的编译通过?我觉得:弄清楚了这个问题才算是彻底的解决了楼主提出的问题。