安卓面试基础知识总结(共33页).docx

上传人:飞****2 文档编号:14944988 上传时间:2022-05-09 格式:DOCX 页数:33 大小:172.58KB
返回 下载 相关 举报
安卓面试基础知识总结(共33页).docx_第1页
第1页 / 共33页
安卓面试基础知识总结(共33页).docx_第2页
第2页 / 共33页
点击查看更多>>
资源描述

《安卓面试基础知识总结(共33页).docx》由会员分享,可在线阅读,更多相关《安卓面试基础知识总结(共33页).docx(33页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精选优质文档-倾情为你奉上1 Activity1.1 Activity的概念是Android应用层开发的四大组件之一,主要负责和用户交互部分,有自己的生命周期,在其上可以布置按钮,文本框等各种控件,简单来说就是Android的UI部分。1.2 Activity与View的区别1) Activity是四大组件中唯一一个用来和用户进行交互的组件。可以说Activity就是android的视图层。2) 如果再细化,Activity相当于视图层中的控制层,是用来控制和管理View的,真正用来显示和处理事件的实际上是View。3) 每个Activity内部都有一个Window对象, Window对象包含

2、了一个DecorView(实际上就是FrameLayout),我们通过setContentView给Activity设置显示的View实际上都是加到了DecorView中。1.3 Activity生命周期1.3.1 生命周期主干方法描述可被杀死下一个onCreate()在Activity第一次被创建的时候被调用。这里是你做所有初始化设置的地方创建视图、绑定数据至列表等。如果曾经有状态记录(参阅后述SavingActivityState。),则调用此方法时会传入一个包含着此activity以前状态的包对象做为参数否onStart()onStart()在Activity正要变得为用户所见时被调用。

3、数据刷新时候调用!当Activity转向前台时接着调用onResume()在Activity变为隐藏时接着知行onStop()否onResume()onStop()onResume()在Activity开始与用户进行交互之前被调用。此时Activity位于堆栈顶部,并接收用户输入。否onPause()Activity runActivity开始运行onPasue()当系统将要启动另一个 Activity时调用。此方法主要用来将未保存的变化进行持久化,停止类似动画这样耗费CPU的动作等。这一切动作应该在短时间内完成,因为下一个Activity必须等到此方法返回后才会继续。当Activity重新回

4、到前台会执行onResume()【弹出对话框】。当Activity变为用户不可见时会执行onStop()。是onResume()onStop()onStop()当Activity不再为用户可见时调用此方法。这可能发生在它被销毁或者另一个Activity(可能是现存的或者是新的)回到运行状态并覆盖了它。如果Activity再次回到前台跟用户交互则执行onRestart().如果关闭Activity则执行onDestroy()是onRestart()onDestroy()onDestroy()在Activity销毁前调用。这是Activity接收的最后一个调用。这可能发生在Activity结束(调

5、用了它的finish()方法)或因为系统需要空间所以临时的销毁了此Activity的实例时。可以用isFinishing()方法来区分这两种情况。是已经完蛋了,还调用毛线!1.3.2 其他中转方法onRestart()在Activity停止后,在再次启动之前被调用。之后执行onStart().否onStart()1.4 Activity启动模式1.4.1 四种启动模式standard默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。singleTop可以有多个实例,但是不允许多个相同Activity叠

6、加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。singleTask只有一个实例。在同一个应用程序中启动它的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activi

7、ty,这个新的Activity还是会在singleTask的实例的task中。singleInstance只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。1.4.2 配置样例1.5 Activity启动方法1) 在一个Activity中调用startActivity()方法。直接启动Activity,不带请求码。2) 在一个Activity中调用startActivityForResult()方法。带请求码启动Activity。1.6 请求码与响应码请求码(RequestCode)在一个业务中可能在两个按钮被单击事件中打开同一个A

8、ctivity,但我们在onActivityResult事件中如何判断是哪个按钮打开了新的Activity?请求码就是为解决这个问题的,那么我们打开新的Activity时应该使用startActivityForResult(intent, 1);。其中的第二个参数就是请求码。结果码(ResultCode)在一个业务中可能要打开多个不同的Activity,那关闭Activity时在onActivityResult事件中我们如何知道关闭的是哪一个Activity呢?结果码就是为解决这个问题的,那么我们打开新的Activity时应该使用setResult(2, intent);或在关闭Activit

9、y前调用ActivityObj.setResult(2);。其中的第一个参数就是结果码。在onActivityResult事件中,通过判断resultCode更可知道是哪个Activity被关闭了。2 BroadcastReceiver2.1 概念BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。2.2 应用场景在Android系统中,广播体现在方方面面:eg:1. 当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;2. 当锁屏或者点亮屏幕时就会产生一条广播,接收这条广播就可以实现一些暂停或者开启一些耗电进程的

10、功能。3. 当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;4. 当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度;2.3 注册2.3.1 静态注册2.3.1.1 概念静态注册是在AndroidManifest.xml文件中配置的。2.3.2 动态注册2.3.2.1 概念动态注册需要在代码中动态的指定广播地址并注册。2.3.2.2 需要注意的事项RegisterReceiver是android.content.ContextWrapper类中的方法,Activity和Service都继承了ContextWrapper,

11、所以可以直接调用。在实际应用中,我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。所以,需要在特定的地方执行解除注册操作:生命周期的onDestroy()。有部分广播接受者,涉及到用户的敏感内容,需要在权限文件中声明。如开机完成的广播,用户电量变化的广播,用户网络状态发生改变的广播2.3.3 生命周期1. 广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁2. 广播接收者中不要做一些耗时的工作,否则会弹出

12、Application No Response错误对话框3. 最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉4. 耗时的较长的工作最好放在服务中完成3 Service3.1 概念服务是看不到界面的,,就是一个没有界面的Activity, 并且长期在后台运行的一个组件.。3.2 为什么用服务?进程优先级, 回收时是从51, 从低到高Foreground process 前台进程Visible process 可视进程Service process 服务进程Background process 后台进程Empty process 空进程回

13、收的优先级: 先回收空进程, 一个一个回收的, 当内存够用时, 不再回收空进程. 如果空进程回收完毕后, 内存还是不够用时, 继续向上一个一个的回收后台进程. 依次类推.当系统内存不够用时, 需要回收服务进程时, 当系统内存又够用时, 会重新启动服务. 当用户去手动的把服务关闭时, 服务不会再重启了3.3 作用由于ANR对Activity和BroadcastReceiver响应时间的限制(Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒),使得在其中都不适合执行较耗时操作,这样像网络、数据库、复杂计算这类耗时操作的执行就需要一个组件来承担。Service

14、作为Android四大组件之一,其功能之一就是耗时操作的执行,主要功能如下:a. 执行需要长时间运行的操作,这个操作不与用户进行交互,如网络下载、大文件I/O、复杂计算、监听手机状态。b. 应用内或应用间数据通信,Android每个应用程序都在自己的dalvik虚拟机中运行,一个应用是不允许访问其他应用的内存信息的,为此Android引入了Content Provider在不同应用间共享数据,BroadcastReceiver广播信息给不同应用程序,但Content Provider更多用于数据的共享,BroadcastReceiver广播的信息会被所有应用接收较耗费系统资源,对于两个应用间动

15、态的进行交互还需要通过Service来完成。3.4 启动方式3.4.1 直接启动Activity开启完服务后就不管服务了. Activity和服务没有关系. startService开启的服务,只有stopService可以关闭3.4.2 绑定启动绑定服务, 生命周期方法会执行: onUnbind - onDestory 服务销毁了.在activity中调用service中的方法.步骤:调用bindService方法绑定服务1. 在Activity中定义一个连接桥的内部类, 会在bindService方法传递给service.2. 在service服务中onBind方法中返回一个IBinder

16、接口对象.3. 在service类中定义一个IBinder的内部实现类, 在onBind方法返回.4. 当onBinder方法返回完对象后, activity中连接桥里的onServiceConnected会被调用, 其中形参IBinder service就是service类中onBind返回的对象.5. activity得到了service中的内部类对象, 点击按钮是调用内部类中的forwardBuyTicket方法, 此方法会转调服务中buyTicket方法.3.5 生命周期Service的生命周期(适用于2.1及以上)1.被startService的无论是否有任何活动绑定到该Servic

17、e,都在后台运行。onCreate(若需要) - onStart(int id, Bundle args).多次startService,则onStart调用多次,但不会创建多个Service实例,只需要一次stop。该Service一直后台运行,直到stopService或者自己的stopSelf()或者资源不足由平台结束。2.被bindService的调用bindService绑定,连接建立服务一直运行。未被startService只是BindService,则onCreate()执行,onStart(int,Bund,le)不被调用;这种情况下绑定被解除,平台就可以清除该Service(

18、连接销毁后,会导致解除,解除后就会销毁)。3.被启动又被绑定类似startService的生命周期,onCreate onStart都会调用。4.停止服务时stopService时显式onDestroy()。或不再有绑定(没有启动时)时隐式调用。有bind情况下stopService()不起作用。4 ContentProvider 4.1 ContentProvider 数据库在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据。 不能将数据库设为WORLD_READABLE,每个数据库都只能创建它的包访问, 这意味着只有由创建数据库的进程可访问它。如果需要

19、在进程间传递数据, 则可以使用AIDL/Binder或创建一个ContentProvider,但是不能跨越进程/包边界直接来使用数据库。 一个Content Provider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此Content Provider的各种数据类型。 也就是说,一个程序可以通过实现一个Content Provider的抽象接口将自己的数据暴露出去。 外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要, 重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序

20、的数据,也可以删除程序的数据, 当然,中间也会涉及一些权限的问题。下边列举一些较常见的接口,这些接口如下所示。 query(Uri uri, String projection, String selection, String selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor。 insert(Uri url, ContentValues values):将一组数据插入到Uri 指定的地方。 update(Uri uri, ContentValues values, String where, String selectionArgs):

21、更新Uri指定位置的数据。 delete(Uri url, String where, String selectionArgs):删除指定Uri并且符合一定条件的数据。4.2 ContentResolver外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的 ContentResolver实例。 ContentResolver提供的接口和ContentProvider中需要实现的接口对应,主要有以下几个。 query(Uri uri, String project

22、ion, String selection, String selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor。 insert(Uri url, ContentValues values):将一组数据插入到Uri 指定的地方。 update(Uri uri, ContentValues values, String where, String selectionArgs):更新Uri指定位置的数据。 delete(Uri url, String where, String selectionArgs):删除指定Uri并且符合一定条件的数据。

23、4.3 ContentObserver在注册,翻译成中文就是内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理。ContentObserver一般和系统或第三方程序提供的Provider一起使用,这些Provider一般情况下会有一个Uri,然后ContentObserver就去监听这些Uri数据的变化,然后做出相应的处理。4.4 ContentProvider和ContentResolver中用到的Uri在ContentProvider和 ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据。我们看下面的

24、例子。 content:/contacts/people/ 这个Uri指定的就是全部的联系人数据。 content:/contacts/people/1 这个Uri指定的是ID为1的联系人的数据。 在上边两个类中用到的Uri一般由3部分组成。 第一部分是方案:content:/ 这部分永远不变 第二部分是授权:contacts 第二部分是路径:people/,people/1(如果没有指定ID,那么表示返回全部)。由于URI通常比较长,而且有时候容易出错,且难以理解。所以,在Android当中定义了一些辅助类,并且定义了一些常量来代替这些长字符串的使用,例如下边的代码:Contacts.Peo

25、ple.CONTENT_URI (联系人的URI)。在我们的实例MyProvider中是如下定义的:public static final String AUTHORITY=com.teleca.PeopleProvider;public static final String PATH_SINGLE=people/#;public static final String PATH_MULTIPLE=people;public static final Uri content_URI=Uri.parse(content:/+AUTHORITY+/+PATH_MULTIPLE);5 Servic

26、e如何向Activity传递数据一个Android程序可以由多个Activity和Servier组成,在这些程序组件之间传递数据的方法有以下几种,每种方法都有其特定的使用途径。5.1 原始数据类型在Activity/Servier之间传递临时性的原始数据,可以使用Intent的putExtras方法来传递数据。若传递的数据需要长久保存,则使用SharedPreference类来完成。5.2 传递对象当在Activity/Servier之间传递不需要长久保存的对象时,可以使用以下几种途径:(1)通过Application类,每个Android应用程序都有一个Application类。当你在程序的

27、AndroidManifest.xml中给Application设定一个名字时,你的程序中就必须有一个Application的子类。这个Application子类会被Android自动实例化,并且是一个全局性的类,它的生命周期和程序的生命周期相同,你可以把一些全局性的对象保存在Application类中。Application类可以通过getApplication()获得。(2)通过HashMap of WeakReferences传递对象。当一个Activity需要向另外一个Activity传递对象时,可以使用一个关键字把对象存在一个HashMap中,并把这个关键字通过Internt的Ext

28、ras发给目标Activity,目标Activity接到该关键字后使用该关键字把对象从HashMap中取出。5.3 在Activity/Service之间传递需要长久保存的对象时,可以使用以下的方式1. Application Preferences2. Files3. contentProviders4. SQLite DB6 AsyncTask 6.1 底层处理底层使用本地线程池机制:1. 核心线程数:线程池中保存的线程数,包括空闲线程,默认为5个2. 线程池中允许的最大线程数,固定为128个+10个阻塞线程3. 当线程数大于核心线程数时,如果线程池中中线程数大于核心线程数5超过一秒事,终

29、止多余的线程,保留五个核心线程数。4. 执行前用于保持任务的队列,此队列仅保持execute方法提交的Runnable任务,固定容量为105. 执行程序创建新线程时使用的工厂6.2 AsyncTask介绍Android的AsyncTask比Handler更轻量级一些(只是代码上轻量一些,而实际上要比handler更耗资源),适用于简单的异步处理。首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。 Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装

30、过的后台任务类,顾名思义就是异步任务。AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。 AsyncTask定义了三种泛型类型 Params,Progress和Result。Params 启动任务执行的输入参数,比如HTTP请求的URL。Progress 后台任务执行的百分比。Result 后台执行任务最终返回的结果,比如String。使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:doInBackground(Params) 后台执行,

31、比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress)来更新任务的进度。onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回有必要的话你还得重写以下这三个方法,但不是必须的:onProgressUpdate(Progress) 可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。onP

32、reExecute()这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。onCancelled() 用户调用取消时,要做的操作使用AsyncTask类,以下是几条必须遵守的准则:Task的实例必须在UI thread中创建;execute方法必须在UI thread中调用;不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params.), onProgressUpdate(Progress.)这几个方法;该task只能被执行一次,否则多次调用时将会出现异常;6.3 AsyncT

33、ask实现的原理和适用的优缺点AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.使用的优点:简单,快捷过程可控 使用的缺点:在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.7 Handler7.1 Handler异步实现的原理和适用的优缺点1. Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列)。 2. Handler: 你可以构造Handler对象来与Looper沟通

34、,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。3. Message Queue(消息队列):用来存放线程放入的消息。4. 线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。在Handler 异步实现时,涉及到 Handler, Looper, Message, MessageQueue四个对象,实现异步的流程是主线程启动Thread(子线程)运行并生成Message放到MessageQueue,Looper从MessageQueue中获取Message

35、并传递给Handler,Handler逐个获取Looper中的Message,并进行UI变更。使用的优点:结构清晰,功能定义明确对于多个后台任务时,简单,清晰使用的缺点:在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)7.2 Handler介绍Handler主要接受子线程发送的数据, 并用此数据配合主线程更新UI.当应用程序启动时,Android首先会开启一个主线程, 主线程为管理界面中的UI控件,进行事件分发,更新UI只能在主线程中更新,子线程中操作是危险的。这个时候,Handler就需要出来解决这个复杂的问题。由于Handler运行在主线程中(UI线程中),它与子线程可以通过Me

36、ssage对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传递)Message对象(里面包含数据), 把这些消息放入主线程队列中,配合主线程进行更新UI。7.3 Handler的特点Handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中,它有两个作用: (1)安排消息或Runnable 在某个主线程中某个地方执行 (2)安排一个动作在不同的线程中执行Handler中分发消息的一些方法post(Runnable)postAtTime(Runnable,long)post

37、Delayed(Runnable long)sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message,long)sendMessageDelayed(Message,long)以上post类方法允许你排列一个Runnable对象到主线程队列中,sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.7.4 综上所述数据简单使用AsyncTask:实现代码简单,数据量多且复杂使用handler+thread :相比较AsyncTask来说能更好的利用系统资源且高效8 ListView8

38、.1 ListView优化8.1.1 简介在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建。ListView加载数据都是在public View getView(int position, View convertView, ViewGroup parent) 方法中进行的(要自定义listview都需要重写listadapter:如BaseAdapter,Simp

39、leAdapter,CursorAdapter的等的getvView方法),优化listview的加载速度就要让convertView匹配列表类型,并最大程度上的重新使用convertView。8.1.2 getview的加载方法一般有以下三种种方式:1. 最慢的加载方式是每一次都重新定义一个View载入布局,再加载数据2. 正确的加载方式是当convertView不为空的时候直接重新使用convertView从而减少了很多不必要的View的创建,然后加载数据3. 最快的方式是定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为空时重新使用即可8.1.3

40、 补充当处理一些耗时的资源加载的时候需要做到以下几点,以使你的加载更快更平滑:1. 适配器在界面主线程中进行修改2. 可以在任何地方获取数据但应该在另外一个地方请求数据3. 在主界面的线程中提交适配器的变化并调用notifyDataSetChanged()方法8.2 ListView的图文混合显示8.2.1 异步加载图片基本思想: 1.先从内存缓存中获取图片显示(内存缓冲) 2.获取不到的话从SD卡里获取(SD卡缓冲) 3.都获取不到的话从网络下载图片并保存到SD卡同时加入内存并显示(视情况看是否要显示) 8.2.2 具体优化优化一:先从内存中加载,没有则开启线程从SD卡或网络中获取,这里注意

41、从SD卡获取图片是放在子线程里执行的,否则快速滑屏的话会不够流畅。优化二:在adapter里新建一个busy变量,表示listview是否处于滑动状态,如果是滑动状态则仅从内存中获取图片,没有的话无需再开启线程去外存或网络获取图片。优化三:利用线程池在从网络获取图片时,先是将其保存到sd卡,然后再加载到内存,这么做的好处是在加载到内存时可以做个压缩处理,以减少图片所占内存资料与源码实现(见附件)8.2.3 关于图片错位的处理图片错位问题的本质源于我们的listview使用了缓存convertView,假设一种场景,一个listview一屏显示九个item,那么在拉出第十个item的时候,事实上

42、该item是重复使用了第一个item,也就是说在第一个item从网络中下载图片并最终要显示的时候其实该item已经不在当前显示区域内了,此时显示的后果将是在可能在第十个item上输出图像,这就导致了图片错位的问题。所以解决之道在于可见则显示,不可见则不显示。在ImageLoader里有个imageViews的map对象,就是用于保存当前显示区域图像对应的url集,在显示前判断处理一下即可。9 JNI9.1 快速智能开发步骤1. 配置NDK目录结构(只需一次)2. 添加本地支持:右键选中工程,Android ToolsAdd native support3. 将cpp代码改成c代码,注意Andr

43、oid.mk文件也要修改,刷新工程,删除obj目录4. 声明本地方法,实现对应c代码实现:Javah+全类名 生成本地方法标头文件,把头文件剪切到jni目录下,c代码引用头文件,实现头文件里的方法。5. 实现对应的c代码6. 交叉编译,一锤子敲下去7. 使用静态代码块,引用库函数,调用方法9.2 开发中常见的JNI问题9.2.1 错误一10-31 06:42:33.645: E/AndroidRuntime(805): java.lang.UnsatisfiedLinkError: Native method not found: com.example.ndk2.MainActivity.h

44、ello_From_C:()Ljava/lang/String;1. 引入的函数库名字不对,或者没有引入2. java方法和c方法不对应3. 部署的平台有问题9.2.2 错误二当前工程报错,但是没有任何文件有错误,有可能Android.mk有问题在Android.mk文件中不要用到全角空格或者回车9.2.3 错误3在C代码中有编译时异常,在控制台上会提示9.2.4 错误410-31 06:53:23.165: A/libc(2075): Fatal signal 11 (SIGSEGV) at 0x476a415c (code=2), thread 2075 (om.example.ndk2)

45、下面打印一大堆debug信息C代码中有运行时异常9.3 应用场景1. 输出日志2. 收集用户反馈信息3. 用户登录4. 加密算法5. 电商数据加密10 静默安装10.1 方式一:定制ROMGoogle的安全策略要求任何应用应该提示APK安装包的权限,对于一些内置特定厂商应用,可以跳过安装过程的信息加快安装,或者运营商强制安装。10.2 方式二:查看系统源码10.2.1 基本原理在窗口中点击一个APK时,触发单击事件,PackageInstaller接收系统服务PackageManagerService传来的intent信息,传来的Intent信息中有APK的一些参数。实现的关键是区分一般APK

46、和特定APK。通过传给PackageManagerService的intent中添加特别的参数,PackageInstaller接收后进行判断,进行特别的隐藏安装流程。这个实现只能通过程序调用的方式安装。 安装过程的信息窗口在PackageInstallActivity.java中实现的。安装过程的信息窗口有4个:需要实现一个PakkageInstallActivityHide.JAVA的文件,去掉下面的dialog和窗口安装权限确认窗口:installPermissionConfirm安装进度条:installProgress安装结果窗口:installResult安装错误提示对话框10.2.2 具体实现(方法一)1. 在Androidmainfest.xml声明一个特定的intent:android.intent.action.VIEW.HIDE,由PackageInstallActivityHide.java来接受注意:2. 实现PakkageInstallActivityHide.java,UninstallerActivityHide.java。 只需把Pakk

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁