如何反编译 android dalvik虚拟机中 /data/dalvik-cache/arm 下的文件

android 安全(30)
转:/showthread.php?p=1363029#post1363029
1、data/dalvik-cache&:&存放已经安装的APK对应的odex文件,这类odex文件仍然以dex作为后缀,保存形式如下:apk路径@apk名@classes.dex。该目录下的odex如果直接替换APK中的classes.dex,重打包后APK是不能正常运行的。
2、system/framework:&APK成功安装后,依赖的Jar包会复制到该目录下。
3、etc/permissions:&存放xml格式文件。这些xml文件是APK依赖的JAR包的映射路径,例如:APK中依赖了一个jar包名为com.test.jar,则在该目录下回生成com.test.xml,里面的路径映射描述如下:
&?xml&version=&1.0&&encoding=&utf-8&?&
&permissions&
&&&&&library&name=&com.test&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&file=&/system/framework/com.test.jar&/&
&/permissions&
反编译该APK,可以查看AndroidManifest.xml里面有如下描述:
&uses-library&android:name=&com.test.jar&/&&&
4、/data/app:&存放用户安装的APK,文件名格式如:com.test.testdemo-1.apk,或者com.test.testdemo-2.apk,其中的“-1”、“-2”表示:当该APK第一次被安装为“-1”,重复安装后变成“-2”,如果再次安装又从“-1”开始标记,如此反复循环。
5、/system/app:存放系统APK(设备自带的APK安装包),该目录下有些APK是有两部分组成的,如test.apk&和&test.odex,如果只拷贝test.apk到其他设备安装是不能成功的,要先把test.odex转换成test.dex格式(odex2dex工具下载地址:/p/android-apktool/downloads/list),然后重打包到test.apk里面,才能正常安装
6、、data/data&:用户成功安装APK后,会生成相应的文件夹目录,如安装了包名为com.test.testdemo的test.apk,就会生成文件夹com.test.testdemo,进入这个目录,通常有如下一些子目录:
1):databases:&存放APK中使用的的数据库&;
2):lib&:存放so包;
3)shared_prefs:&用SharedPreferences存储数据的xml格式文件;
7、data/system:&该目录下的packages.xml文件主要记录了,当前设备已经安装的APK所对应的配置信息,如果发现一个APK提示安装失败,可以试着删除该文件里记录当前APK的package信息,然后重新安装&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1079470次
积分:13730
积分:13730
排名:第979名
原创:235篇
转载:646篇
评论:139条
(1)(16)(12)(20)(13)(5)(13)(5)(28)(11)(7)(36)(30)(30)(28)(36)(17)(27)(18)(11)(5)(11)(20)(20)(3)(16)(22)(18)(11)(14)(10)(17)(8)(10)(6)(7)(7)(5)(8)(2)(11)(14)(3)(3)(2)(22)(3)(7)(24)(7)(9)(14)(3)(3)(1)(2)(1)(1)(5)(4)(9)(2)(5)(3)(1)(2)(2)(4)(1)(5)(3)(2)(2)(1)(1)(1)(2)(1)(4)(2)(3)(4)(25)(13)(7)(24)(31)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'1、在多线程编程这块,我们经常要使用Handler,Thread和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢?
答:Android的CPU分配的最小单元是线程,Handler一般是在某个线程里创建的,因而Handler和Thread就是相互绑定的,一一对应。而Runnable是一个接口,Thread是Runnable的子类。所以说,他俩都算一个进程。HandlerThread顾名思义就是可以处理消息循环的线程,他是一个拥有Looper的线程,可以处理消息循环。与其说Handler和一个线程绑定,不如说Handler是和Looper一一对应的。最后需要说明的是,在UI线程(主线程)中:&&
mHandler=new Handler(); 
mHandler.post(new Runnable(){
  void run(){
  //执行代码...}
  这个线程其实是在UI线程之内运行的,并没有新建线程。
  常见的新建线程的方法是:
  Thread thread = new Thread();
  thread.start();
  HandlerThread thread = newHandlerThread(&string&);
  thread.start();
2、如何设定应用程序为系统级别的应用?
答:apk&获取system权限;如何获取如下:
解释连接:
&第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:
在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId=&android.uid.system&这个属性。
修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
使用mm命令来编译,生成的apk就有修改系统时间的权限了。
&&&&&&&第二个方法是直接把eclipse编出来的apk用系统的签名文件签名
加入android:sharedUserId=&android.uid.system&这个属性。
使用eclipse编译出apk文件。
使用目标系统的platform密钥来重新给apk文件签名。首先找到密钥文件,在我ndroid源码目录中的位置是&build/target/product/security&,下面的platform.pk8和platform.x509.pem两个文件。然后用Android提供的Signapk工具来签名,signapk的源代码是在&build/tools/signapk&下,编译后在out/host/linux-x86/framework下,用法为java
-jarsignapk.jar &platform.x509.pem platform.pk8 input.apk output.apk&。
&&&&&&&加入android:sharedUserId=&android.uid.system&这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来修改系统时间了。
&&&&&&&只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE
:=platform其实就是用这两个key来签名。
&&&&&&&这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示&Package...
has no signatures that match those in shared user android.uid.system&,这样也是保护了系统的安全。
3、谈谈Android的IPC(进程间通信)机制
答:http://blog.csdn.net/luoshengyang/article/details/6618363
Android系统中,每一个应用程序都是由一些Activity和Service组成的,这些Activity和Service有可能运行在同一个进程中,也有可能运行在不同的进程中,android的IPC机制也就是Binder机制,Android系统是基于Linux内核的,而Linux内核继承和兼容了丰富的Unix系统进程间通信(IPC)机制,&但是,Android系统没有采用上述提到的各种进程间通信机制,而是采用Binder机制,Binder是一种进程间通信机制,它是一种类似于COM和CORBA分布式组件架构,通俗一点,其实是提供远程过程调用(RPC)功能。从英文字面上意思看,Binder具有粘结剂的意思,那么它把什么东西粘结在一起呢?在Android系统的Binder机制中,由一系统组件组成,分别是Client、Server、Service
Manager和Binder驱动程序,其中Client、Server和Service Manager运行在用户空间,Binder驱动程序运行内核空间。Binder就是一种把这四个组件粘合在一起的粘结剂了,其中,核心组件便是Binder驱动程序了,Service Manager提供了辅助管理的功能,Client和Server正是在Binder驱动和ServiceManager提供的基础设施上,进行Client-Server之间的通信;
&1. Client、Server和Service Manager实现在用户空间中,Binder驱动程序实现在内核空间中
&&2. Binder驱动程序和Service Manager在Android平台中已经实现,开发者只需要在用户空间实现自己的Client和Server
&&&3.Binder驱动程序提供设备文件/dev/binder与用户空间交互,Client、Server和Service Manager通过open和ioctl文件操作函数与Binder驱动程序进行通信
&&4. Client和Server之间的进程间通信通过Binder驱动程序间接实现
&&&5. Service Manager是一个守护进程,用来管理Server,并向Client提供查询Server接口的能力
4、apk安装卸载的原理
APK安装可以通过以下四种方式:
1. 系统应用安装,开机时完成系统应用的检查,没安装就安装,安装就跳过,无安装界面。
2. 网络下载应用安装,通过market应用完成,无安装界面。
3. ADB工具安装,无安装界面
4. 通过SD卡来安装apk,有安装界面,由packageinstaller.apk应用处理安装及卸载过程的界面。
应用安装涉及到如下几个目录:
system/app &&&&系统自带的应用程序,无法删除
data/app &&&&用户程序安装的目录,有删除权限
data/data &&&&存放应用程序的数据
Data/dalvik-cache &&将apk中的dex文件安装到dalvik-cache目录下
(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)
安装过程:复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录。
&卸载过程:删除安装过程中在上述三个目录下创建的文件及目录。
5、如何做适配
1)android有H、L、M、X、XX四个不同的文件夹存放不同分辨率的图片,系统会自动加载
偏移量d的设置可以在values-hpdi,values-mdpi,values-ldpi三种文件夹中的dimens.xml文件进行设置
值得一提的是:
&&&&&dimen&name=“bitmap_common_topoffset”&40dp&/dimen&
&&&&&dimen&name=“bitmap_common_bottomoffset”&-14dp&/dimen&
这里的负数是完全起作用的,系统会认为它是一个负值
3)各大手机厂商对于Android操作系统都有或多或少的改动,当然这些改动会对我们应用程序产生某些影响
&&(1)系统源代码中连接music服务的aidl文件所在包名:com.android.music&
&&(2)LG则可能将该aidl文件修改所在的包(例如修改为 com.android.music.player),并且修改其中的文件内容(增加一个方法,或者减少几个方法,或者修改方法名称)那么我们的应用要想在LG的手机上发布,那么我们就必须改变所要连接的aidl文件,必须跟LG厂商修改的完全一致。
6、是否进行过apk反编译,如何防止反编译
&&&& Android反编译工具
·&&&&&& &+&
防止反编译:
·&&&&&& 代码加密
这方式,也只能想想,一旦你自己加密了,Android系统都不认识你了,还怎么运行?(如果有那估计就是eoe现在推的爱加密吧).
·&&&&&& 代码混淆
这种方式,其实我不大愿意将他归类于防止反编译,从Android、Java编译原理上来说,针对自身代码做混淆等操作,必然防止不了反编译这个事实。他能做到的就是将字符,函数等混淆成各种a,b,c,d,1,2,3等。
这种方式一般称为,
妨碍对反编译代码的阅读、观看和理解
Android中主要是针对&proguard.cfg&的配置来实现。
具体的实现网上针对这部分的解释已经太多,所以这里不详细介绍了。
·&&&&&& 动态加载类
这种方式的启发是根据web端来的。Web端你要防止,那就不发布呗。
所以我们可以将我们重要的源码,丢在服务器上,必要的时候通过类去加载重要类。来防止核心代码被反编译。
·&&&&&& 用NDK开发核心代码
从上面已经能知道,C/C++等编译型语言的反汇编难度。所以我们可以放心的使用NDK去开发,生成SO库文件再来调用。
PS:部分资源文件若十分珍贵,可以通过 #include直接编译到库里(当然内存可能就大了),这种方式可以自己考虑。
7、Android的动画分类以及两种动画的阐述
& & & &&又称“补间动画”、“中间动画”,最早接触Tween类是在学习Flash时候,使用ActionScript做动画的时候,使用过类Tween。
& & & &&Tween动画主要的功能是在绘制动画前设置动画绘制的轨迹,包括时间, 位置 ,等等。但是Tween动画的缺点是它只能设置起始点与结束点的两帧,中间过程全部由系统帮我们完成。所以在帧数比较多的游戏开发中是不太会用到它的。
& & & &Tween一共提供了4中动画的效果
& & & &Scale:缩放动画
& & & &Rotate:旋转动画
& & & &Translate:移动动画
& & & &Alpha::透明渐变动画
&&&&&& 又称帧动画,主要显示方式是&animation-list&为动画的总标签,这里面放着帧动画&item&标签,也就是说若干&item&标签的帧 组合在一起就是帧动画了。&animation-list & 标签中android:oneshot=&false&这是一个非常重要的属性,默认为false
表示 动画循环播放, 如果这里写true 则表示动画只播发一次。 &item&标签中记录着每一帧的信息android:drawable=&@drawable/a&表示这一帧用的图片为&a&,下面以此类推。&android:duration=&100& 表示这一帧持续100毫秒,可以根据这个值来调节动画播放的速度。
&8、AIDL全称,如何工作,可处理那些数据
答:AIDL的英文全称是Android Interface Define Language
当A进程要去调用B进程中的service时,并实现通信,我们通常都是通过AIDL来操作的
首先我们在net.blogjava.mobile.aidlservice包中创建一个RemoteService.aidl文件,在里面我们自定义一个接口,含有方法get。ADT插件会在gen目录下自动生成一个RemoteService.java文件,该类中含有一个名为RemoteService.stub的内部类,该内部类中含有aidl文件接口的get方法。
说明一:aidl文件的位置不固定,可以任意
然后定义自己的MyService类,在MyService类中自定义一个内部类去继承RemoteService.stub这个内部类,实现get方法。在onBind方法中返回这个内部类的对象,系统会自动将这个对象封装成IBinder对象,传递给他的调用者。
其次需要在AndroidManifest.xml文件中配置MyService类,代码如下:
&!-- 注册服务 --&&
&service android:name=&.MyService&&
& &intent-filter&
&& &!--& 指定调用AIDL服务的ID& --&
&&&&&&&actionandroid:name=&net.blogjava.mobile.aidlservice.RemoteService&/&
&& &/intent-filter&
&/service&
为什么要指定调用AIDL服务的ID,就是要告诉外界MyService这个类能够被别的进程访问,只要别的进程知道这个ID,正是有了这个ID,B工程才能找到A工程实现通信。
说明:AIDL并不需要权限
&&&&& 首先我们要将A工程中生成的RemoteService.java文件拷贝到B工程中,在bindService方法中绑定aidl服务
&&&&& 绑定AIDL服务就是将RemoteService的ID作为intent的action参数。
&&&&& 说明:如果我们单独将RemoteService.aidl文件放在一个包里,那个在我们将gen目录下的该包拷贝到B工程中。如果我们将RemoteService.aidl文件和我们的其他类存放在一起,那么我们在B工程中就要建立相应的包,以保证RmoteService.java文件的报名正确,我们不能修改RemoteService.java文件
&&&&&&&&&bindService(newInten(&net.blogjava.mobile.aidlservice.RemoteService&),serviceConnection,Context.BIND_AUTO_CREATE);
&&&&& ServiceConnection的onServiceConnected(ComponentName name, IBinderservice)方法中的service参数就是A工程中MyService类中继承了RemoteService.stub类的内部类的对象。
9、Android系统中GC什么情况下不会出现内存泄露
数据库的cursor没有关闭
2.构造adapter时,没有使用缓存contentview
&& 衍生listview的优化问题-----减少创建view的对象,充分使用contentview,可以使用一静态类来优化处理getview的过程/
3.Bitmap对象不使用时采用recycle()释放内存
4.activity中的对象的生命周期大于activity
调试方法: DDMS==& HEAPSZIE==&dataobject==&[TotalSize]
10、什么情况会导致Force Close ?如何避免?能否捕获导致其的异常?
答:一般像空指针啊,可以看起logcat,然后对应到程序中 来解决错误
11、activity的4种模式,以及不同模式的作用。
activity有四种启动模式,分别为standard,singleTop,singleTask,singleInstance。如果要使用这四种启动模式,必须在manifest文件中&activity&标签中的launchMode属性中配置,如:
&activity&android:name=&.app.InterstitialMessageActivity& &
& & & & & android:label=&@string/interstitial_label& &
& & & & & android:theme=&@style/Theme.Dialog& &
& & & & & android:launchMode=&singleTask& &
&/activity&&
标准启动模式,也是activity的默认启动模式。在这种模式下启动的activity可以被多次实例化,即在同一个任务中可以存在多个activity的实例,每个实例都会处理一个Intent对象。如果Activity A的启动模式为standard,并且A已经启动,在A中再次启动Activity A,即调用startActivity(new Intent(this,A.class)),会在A的上面再次启动一个A的实例,即当前的桟中的状态为A--&A。
如果一个以singleTop模式启动的activity的实例已经存在于任务桟的桟顶,那么再启动这个Activity时,不会创建新的实例,而是重用位于栈顶的那个实例,并且会调用该实例的onNewIntent()方法将Intent对象传递到这个实例中。举例来说,如果A的启动模式为singleTop,并且A的一个实例已经存在于栈顶中,那么再调用startActivity(new
Intent(this,A.class))启动A时,不会再次创建A的实例,而是重用原来的实例,并且调用原来实例的onNewIntent()方法。这是任务桟中还是这有一个A的实例。
如果以singleTop模式启动的activity的一个实例已经存在与任务桟中,但是不在桟顶,那么它的行为和standard模式相同,也会创建多个实例。
singleTask
谷歌的官方文档上称,如果一个activity的启动模式为singleTask,那么系统总会在一个新任务的最底部(root)启动这个activity,并且被这个activity启动的其他activity会和该activity同时存在于这个新任务中。如果系统中已经存在这样的一个activity则会重用这个实例,并且调用他的onNewIntent()方法。即,这样的一个activity在系统中只会存在一个实例。
其实官方文档中的这种说法并不准确,启动模式为singleTask的activity并不会总是开启一个新的任务。详情请参考,在本文后面也会通过示例来进行验证。
singleInstance
总是在新的任务中开启,并且这个新的任务中有且只有这一个实例,也就是说被该实例启动的其他activity会自动运行于另一个任务中。当再次启动该activity的实例时,会重用已存在的任务和实例。并且会调用这个实例的onNewIntent()方法,将Intent实例传递到该实例中。和singleTask相同,同一时刻在系统中只会存在一个这样的Activity实例。
12、NDK是什么
NDK:NativeDevelopment Kit
&AndroidNDK是一个让开发人员在Android应用中嵌入使用本地代码编写的组件的工具集。
Android应用运行在Dalvik虚拟机中。NDK允许开发人员使用本地代码语言(例如C和C++)实现应用的部分功能。这样以代码重用的形式能够给某类应用提供方便,而且在某些情况下能提高运行速度(感谢老婆的帮助)。
13、请解释下Android程序运行时权限与文件系统权限的区别
答:运行时权限Dalvik( android授权)
&&& 文件系统 linux 内核授权
14、横竖屏切换时候activity的生命周期?
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges=&orientation&时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges=&orientation|keyboardHidden&时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
15、如何设定Android应用为系统应用
将自己的应用方到android源代码的packages/apps/目录下,添加Android.mk文件&
2 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId=&android.uid.system&这个属性。&
3 修改Android.mk文件,加入LOCAL_CERTIFICATE:= platform这一行&
4 使用mm命令来编译,生成的apk就有同system一样的权限了。&
5 在android根目录下用make snod重新生成system.img&
6 启动emulator运行下应用看看是否好了。&
16、如何将SQLite数据库(dictionary.db文件)与apk文件一起发布?
可以将dictionary.db文件复制到Eclipse Android工程中的res aw目录中。所有在res aw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db文件复制到res aw目录中
17.如何将打开res aw目录中的数据库文件?
解答:在Android中不能直接打开resaw目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或SD卡的某个目录中,然后再打开该数据库文件。复制的基本方法是使用getResources().openRawResource方法获得res aw目录中资源的 InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法来打开任意目录中的SQLite数据库文件。
18、线程中wait和sleep的区别
答:wait释放线程锁,sleep不是线程锁,wait不占用系统资源sleep占用资源
19、两种方法注册broadcaseReceiver,及区别。
答:动态注册和静态注册一个BroadcastReceiver的区别:
动态注册较静态注册灵活。实验证明:当静态注册一个BroadcastReceiver时,不论应用程序是启动与否。都可以接受对应的广播。
动态注册的时候,如果不执行unregisterReceiver();方法取消注册,跟静态是一样的。但是如果执行该方法,当执行过以后,就不能接受广播了。
20、在android中,请简述jni的调用过程。
1)安装和下载Cygwin,下载 Android NDK
2)在ndk项目中JNI接口的设计
3)使用C/C++实现本地方法
4)JNI生成动态链接库.so文件
5)将动态链接库复制到java工程,在java工程中调用,运行java工程即可
21、简述Android应用程序结构是哪些?
Android应用程序结构是:
Linux Kernel(Linux内核)、
Libraries(系统运行库或者是c/c++核心库)、
Application Framework(开发框架包)、
Applications&(核心应用程序)
22、请继承SQLiteOpenHelper实现:
1).创建一个版本为1的“diaryOpenHelper.db”的数据库,
2).同时创建一个 “diary” 表(包含一个_id主键并自增长,topic字符型100
长度, content字符型1000长度)
3).在数据库版本变化时请删除diary表,并重新创建出diary表。
publicclass DBHelper& extendsSQLiteOpenHelper{
public final static String DATABASENAME =&diaryOpenHelper.db&;
public final static int DATABASEVERSION =1;
//创建数据库
public DBHelper(Context context,Stringname,CursorFactory factory,int version)
super(context, DATABASENAME, factory, DATABASEVERSION);
//创建表等机构性文件
public void onCreate(SQLiteDatabase db)
String sql =&create tablediary&+
&_idinteger primary key autoincrement,&+
&topicvarchar(100),&+
&contentvarchar(1000)&+
db.execSQL(sql);
//若数据库版本有更新,则调用此方法
public void onUpgrade(SQLiteDatabasedb,int oldVersion,int newVersion)
String sql = &drop table ifexists diary&;
db.execSQL(sql);
this.onCreate(db);
23、页面上现有ProgressBar控件progressBar,请用书写线程以10秒的的时间完成其进度显示工作。
publicclass ProgressBarStu extends Activity {
private ProgressBar progressBar =
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar);
//从这到下是关键
progressBar = (ProgressBar)findViewById(R.id.progressBar);
Thread thread = new Thread(newRunnable() {
public void run() {
int progressBarMax =progressBar.getMax();
while(progressBarMax!=progressBar.getProgress())
intstepProgress = progressBarMax/10;
intcurrentprogress = progressBar.getProgress();
progressBar.setProgress(currentprogress+stepProgress);
Thread.sleep(1000);
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
thread.start();
//关键结束
24、请描述下Activity的生命周期。
必调用的三个方法:onCreate() --&onStart() --& onResume(),用AAA表示
(1)父Activity启动子Activity,子Actvity退出,父Activity调用顺序如下
AAA --& onResume () --& onPause() --& onStop() --&onRestart()--& onStart(),onResume() …
(2)用户点击Home,Actvity调用顺序如下
AAA --& onResume () --& onPause() --& onStop() -- Maybe--&onDestroy() – Maybe
(3)调用finish(), Activity调用顺序如下
AAA --& onPause() --& onStop() --& onDestroy()
(4)在Activity上显示dialog,Activity调用顺序如下
(5)在父Activity上显示透明的或非全屏的activity,Activity调用顺序如下
AAA --& onResume () --& onPause()
(6)设备进入睡眠状态,Activity调用顺序如下
AAA --& onFreeze() --& onPause()
25、如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?
在oncreate中写如下取得保存的状态:
if&(savedInstanceState&!=&null&&
&&&&&&&&&&&&&&&savedInstanceState.getInt(&currentposition&)&!=&0)&{&&
&&&&&&&&videoView.seekTo(savedInstanceState.getInt(&currentposition&));&&
重写这个方法保存状态
protected&void&onSaveInstanceState(Bundle&outState)&{&&
&&&&//&TODO&Auto-generated&method&stub&&
&&&&outState.putInt(&currentposition&,&videoView.getCurrentPosition());&&
&&&&Log.v(&tag&,&&onSaveInstanceState&);&&
&&&&super.onSaveInstanceState(outState);&&
当你的程序中某一个Activity A在运行时,主动或被动地运行另一个新的Activity B,这个时候A会执行onSaveInstanceState()。B完成以后又会来找A,这个时候就有两种情况:一是A被回收,二是A没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被收回的就直接执行onResume(),跳过onCreate()了。
26、如何将一个Activity设置成窗口的样式。
在AndroidManifest.xml 中定义Activity的地方一句话android:theme=&@android:style/Theme.Dialog&或android:theme=&@android:style/Theme.Translucent&就变成半透明的
27、如何退出Activity?如何安全退出已调用多个Activity的Application?
对于单一Activity的应用来说,退出很简单,直接finish()即可。
当然,也可以用killProcess()和System.exit()这样的方法。
28、请介绍下ContentProvider是如何实现数据共享的。
创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Contentprovider中,前提是有相同数据类型并且有写入Contentprovider的权限。
29、请解释下在单线程模型中Message、Handler、MessageQueue、Looper之间的关系。
Handler简介:
一个Handler允许你发送和处理Message和Runable对象,这些对象和一个线程的MessageQueue相关联。每一个线程实例和一个单独的线程以及该线程的MessageQueue相关联。当你创建一个新的Handler时,它就和创建它的线程绑定在一起了。这里,线程我们也可以理解为线程的MessageQueue。从这一点上来看,Handler把Message和Runable对象传递给MessageQueue,而且在这些对象离开MessageQueue时,Handler负责执行他们。
Handler有两个主要的用途:
(1)确定在将来的某个时间点执行一个或者一些Message和Runnable对象。
(2)在其他线程(不是Handler绑定线程)中排入一些要执行的动作。
Scheduling Message,即(1),可以通过以下方法完成:
post(Runnable):Runnable在handler绑定的线程上执行,也就是说不创建新线程。
postAtTime(Runnable,long):
postDelayed(Runnable,long):
sendEmptyMessage(int):
sendMessage(Message):
sendMessageAtTime(Message,long):
sendMessageDelayed(Message,long):
post这个动作让你把Runnable对象排入MessageQueue,MessageQueue受到这些消息的时候执行他们,当然以一定的排序。sendMessage这个动作允许你把Message对象排成队列,这些Message对象包含一些信息,Handler的hanlerMessage(Message)会处理这些Message.当然,handlerMessage(Message)必须由Handler的子类来重写。这是编程人员需要作的事。
当posting或者sending到一个Hanler时,你可以有三种行为:当MessageQueue准备好就处理,定义一个延迟时间,定义一个精确的时间去处理。后两者允许你实现timeout,tick,和基于时间的行为。
当你的应用创建一个新的进程时,主线程(也就是UI线程)自带一个MessageQueue,这个MessageQueue管理顶层的应用对象(像activities,broadcastreceivers等)和主线程创建的窗体。你可以创建自己的线程,并通过一个Handler和主线程进行通信。这和之前一样,通过post和sendmessage来完成,差别在于在哪一个线程中执行这么方法。在恰当的时候,给定的Runnable和Message将在Handler的MessageQueue中被Scheduled。
Message简介:
Message类就是定义了一个信息,这个信息中包含一个描述符和任意的数据对象,这个信息被用来传递给Handler.Message对象提供额外的两个int域和一个Object域,这可以让你在大多数情况下不用作分配的动作。
尽管Message的构造函数是public的,但是获取Message实例的最好方法是调用Message.obtain(),或者Handler.obtainMessage()方法,这些方法会从回收对象池中获取一个。
MessageQueue简介:
这是一个包含message列表的底层类。Looper负责分发这些message。Messages并不是直接加到一个MessageQueue中,而是通过MessageQueue.IdleHandler关联到Looper。
你可以通过Looper.myQueue()从当前线程中获取MessageQueue。
Looper简介:
Looper类被用来执行一个线程中的message循环。默认情况,没有一个消息循环关联到线程。在线程中调用prepare()创建一个Looper,然后用loop()来处理messages,直到循环终止。
大多数和message loop的交互是通过Handler。
下面是一个典型的带有Looper的线程实现。
& class LooperThread extends Thread {
&&&&& public Handler mH
&&&&& public void run() {
&&&&&&&&& Looper.prepare();
&&&&&&&&& mHandler = new Handler() {
&&&&&&&&&&&&& publicvoidhandleMessage(Message msg) {
&&&&&&&&&&&&&&&&& // processincomingmessages here
&&&&&&&&&&&&& }
&&&&&&&&& };
&&&&&&&&& Looper.loop();
30、系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原由。
通过直接发送Uri把参数带过去,或者通过manifest里的intentfilter里的data属性
31、什么是ANR如何避免它?
ANR:ApplicationNotResponding,五秒
在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列情况时,Android就会显示ANR对话框了:
对输入事件(如按键、触摸屏事件)的响应超过5秒
意向接受器(intentReceiver)超过10秒钟仍未执行完毕
Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intentbroadcast)。
因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如onCreate()和 onResume()等更应如此。潜在的比较耗时的操作,如访问网络和数据库;或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成(或者是使用异步请求,如数据库操作)。但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束 -- 也不需要调用Therad.wait()或者Thread.sleep()方法。取而代之的是,主线程为子线程提供一个句柄(Handler),让子线程在即将结束的时候调用它(xing:可以参看Snake的例子,这种方法与以前我们所接触的有所不同)。使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过5秒钟不被处理而产生的ANR。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题
本文已收录于以下专栏:
相关文章推荐
成功没有捷径,脚踏实地一步一个脚印,不好高骛远,不急功近利,付出总有回报,不管出于哪个阶段,都要一步一个脚印,踏实的走好每一步。让技术来强大自己,让技术改变世界。
面试时遇到这样的题目
 简述下Android程序运行时权限与文件系统权限的区别?
问题来的太突然,完全没有准备,结果我想到了android 6.0之后推出的
normal p...
要区分apk运行时的拥有的权限与在文件系统上被访问(读写执行)的权限两个概念。 apk程序是运行在虚拟机上的,对应的是Android独特的权限机制,只有体现到文件系统上时才使用linux的权限设置。
一、选择题
1.  下列哪些语句关于内存回收的说明是正确的? () 
A、 程序员必须创建一个线程来释放内存           B、 内存回收程序负责释放无用内存 
C、 内存回收程序允许程序员直接...
精心挑选android面试题-选择填空,还是继续收集!希望对大家有帮助
1.        下列哪些语句关于内存回收的说明是正确的? (b ) A、 程序员必须创建一个线程来释放内存
  B、内存回收程序负责释放无用内存 
  C、内...
前公司做在线教育产品。当时为实现在线答题,完成了以下demo,具体代码是一年多前完成的,比较简单,不再贴出,请参见Github。demo功能包括:
单选:点击选项直接进入下一题。
多选:选择多个选项,...
要区分apk运行时的拥有的权限与在文件系统上被访问(读写执行)的权限两个概念。
apk程序是运行在虚拟机上的,对应的是Android独特的权限机制,只有体现到文件系统上时才使用linux的权限设置。...
一、简答题
1、Objective-C的类可以多重继承么?可以采用多个协议么?
不可以多重继承,可以采用多个协议。
2、#import和#include的区别是什么?#import
     ...
他的最新文章
讲师:王哲涵
讲师:韦玮
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 data dalvik cache 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信