1、在多线程编程这块,我们经常要使用Handler,Thread和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢?
答:可以处理消息循环的线程,他是一个拥有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、如何设定应用程序获取system权限;如何获取如下:
第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:
1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android.uid.system"这个属性。
2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
第二个方法是直接把eclipse编出来的apk用系统的签名文件签名
1. 加入android.uid.system"这个属性。
2. 使用eclipse编译出apk文件。
3. 使用目标系统的platform密钥来重新给apk文件签名。首先找到密钥文件,在我ndroid源码目录中的位置是"build/target/product/security",下面的platform.pk8和platform.x509.pem两个文件。然后用为java -jarsignapk.jar platform.x509.pem platform.pk8 input.apk output.apk"。
加入android.可以配置成运行在同一个进程中。那么把程序的android.只是加入可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE :=platform其实就是用这两个key来签名。
这也有一个问题,就是这样生成的程序只有在原始的可以用,因可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package... has no signatures that match those in shared user uid.system",这样也是保护了系统的安全。
1. Client、Server和Service Manager实现在用户空间中,Binder驱动程序实现在内核空间中
2. Binder驱动程序和Service Manager在驱动程序提供设备文件/dev/binder与用户空间交互,Client、Server和Service Manager通过open和ioctl文件操作函数与Binder驱动程序进行通信
4. Client和Server之间的进程间通信通过Binder驱动程序间接实现
5. Service Manager是一个守护进程,用来管理Server,并向Client提供查询Server接口的能力
答:http://blog.csdn.net/lizhiguo0532/article/details/7077432
http://www.itivy.com/android-apk-setup-method-and-principles.html
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虚拟机的可执行文件,其大小约卸载过程:删除安装过程中在上述三个目录下创建的文件及目录。
<dimen name=“bitmap_common_topoffset”>40dp</dimen>
<dimen name=“bitmap_common_bottomoffset”>-14dp</dimen>
这里的为它是一个负值
3)各大手机厂商对于 比如:
(1)系统源代码中连接music服务的aidl文件所在包名:com.android.music
(2)LG则可能将该aidl文件修改所在的包(例如修改android.music.player),并且修改其中的文件内容(增加一个方法,或者减少几个方法,或者修改方法名称)那么我们的应用要想在LG的手机上发布,那么我们就必须改变所要连接的aidl文件,必须跟LG厂商修改的完全一致。
dex2jar + jdgui
· apktool
· 代码加密
这方式,也只能想想,一旦你自己加密了,代码混淆
这种方式,其实我不大愿意将他归类于防止反编译,从为,
妨碍对反编译代码的阅读、观看和理解
的配置来实现。
具体的实现网上针对这部分的解释已经太多,所以这里不详细介绍了。
· 动态加载类
这种方式的启发是根据web端来的。Web端你要防止,那就不发布呗。
所以我们用NDK开发核心代码
从上面已经能知道,C/C++等编译型语言的反汇编难度。所以我们可以通过 #include直接编译到库里(当然内存可能就大了),这种方式可以自己考虑。
Tween动画主要的功能是在绘制动画前设置动画绘制的轨迹,包括时间, 位置 ,等等。但是Tween动画的缺点是它只能设置起始点与结束点的两帧,中间过程全部由系统帮我们完成。所以在帧数比较多的游戏开发中是不太会用到它的。
Tween一共提供了4中动画的效果
Scale:缩放动画
Rotate:旋转动画
Translate:移动动画
Alpha::透明渐变动画
Frame动画
又称帧动画,主要显示方式是<animation-list>android:oneshot="false"这是一个非常重要的属性,默认android:drawable="@drawable/a"表示这一帧用的图片android:duration="100" 表示这一帧持续100毫秒,可以根据这个值来调节动画播放的速度。
android:label="@string/interstitial_label"
android:theme="@style/Theme.Dialog"
android:launchMode="singleTask"
</activity>
standard
标准启动模式,也是activity的默认启动模式。在这种模式下启动的activity可以存在多个activity的实例,每个实例都会处理一个Intent对象。如果Activity A的启动模式为A-->A。
singleTop
如果一个以singleTop模式启动的activity的实例已经存在于任务桟的桟顶,那么再启动这个Activity时,不会创建新的实例,而是重用位于栈顶的那个实例,并且会调用该实例的onNewIntent()方法将Intent对象传递到这个实例中。举例来说,如果A的启动模式为和standard模式相同,也会创建多个实例。
singleTask
谷歌的官方文档上称,如果一个activity的启动模式为singleTask的activity并不会总是开启一个新的任务。详情请参考 解开Android应用程序组件Activity的"singleTask"之谜,在本文后面也会通过示例来进行验证。
singleInstance
总是在新的任务中开启,并且这个新的任务中有且只有这一个实例,也就是说被该实例启动的其他activity会 自动运行于另一个任务中。当再次启动该activity的实例时,会重用已存在的任务和实例。并且会调用这个实例的onNewIntent()方法,将 Intent实例传递到该实例中。和singleTask相同,同一时刻在系统中只会存在一个这样的Activity实例。
NDK:NativeDevelopment Kit
AndroidNDK是一个让开发人员在Android应用运行在Dalvik虚拟机中。NDK允许开发人员使用本地代码语言(例如C和C++)实现应用的部分功能。这样以代码重用的形式能够给某类应用提供方便,而且在某些情况下能提高运行速度(感谢老婆的帮助)。
动态注册的时候,如果不执行unregisterReceiver();方法取消注册,跟静态是一样的。但是如果执行该方法,当执行过以后,就不能接受广播了。
20、在Android NDK
2)在ndk项目中JNI接口的设计
3)使用C/C++实现本地方法
4)JNI生成动态链接库.so文件
5)将动态链接库复制到java工程,在java工程中调用,运行java工程即可
21、简述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 = null;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar);
//从这到下是关键
progressBar = (ProgressBar)findViewById(R.id.progressBar);
Thread thread = new Thread(newRunnable() {
@Override
public void run() {
int progressBarMax =progressBar.getMax();
try {
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调用顺序如下
AAA
(5)在父Activity上显示透明的或非全屏的activity,Activity调用顺序如下
AAA --< onResume () --< onPause()
(6)设备进入睡眠状态,Activity调用顺序如下
AAA --< onFreeze() --< onPause()
25、如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?
在oncreate中写如下取得保存的状态:
1. if (savedInstanceState != null
2. && savedInstanceState.getInt("currentposition") != 0) {
3.
4. videoView.seekTo(savedInstanceState.getInt("currentposition"));
5. }
重写这个方法保存状态
6. protected void onSaveInstanceState(Bundle outState) {
7. // TODO Auto-generated method stub
8. outState.putInt("currentposition", videoView.getCurrentPosition());
9. Log.v("tag", "onSaveInstanceState");
10. super.onSaveInstanceState(outState);
11. }
当你的程序中某一个Activity A在运行时,主动或被动地运行另一个新的Activity B,这个时候A会执行onSaveInstanceState()。B完成以后又会来找A,这个时候就有两种情况:一是A被回收,二是A没有被回收,被回 收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被 收回的就直接执行onResume(),跳过onCreate()了。
26、如何将一个Activity设置成窗口的样式。
在AndroidManifest.xml 中定义Activity的地方一句话android:style/Theme.Dialog"或android:style/Theme.Translucent"就变成半透明的
27、如何退出Activity?如何安全退出已调用多个Activity的Application?
对于单一Activity的应用来说,退出很简单,直接finish()即可。
当然,也可以理解可以通过以下方法完成:
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,和基于时间的行可以创 建自己的线程,并通过一个Handler和主线程进行通信。这和之前一样,通过post和sendmessage来完成,差别在于在哪一个线程中执行这么 方法。在恰当的时候,给定的Runnable和Message将在Handler的MessageQueue中被Scheduled。
Message简介:
Message类就是定义了一个信息,这个信息中包含一个描述符和任意的数据对象,这个信息被用来传递给Handler.Message对象提供额外的两个int域和一个Object域,这可以通过Looper.myQueue()从当前线程中获取MessageQueue。
Looper简介:
Looper类被用来执行一个线程中的message循环。默认情况,没有一个消息循环关联到线程。在线程中调用prepare()创建一个Looper,然后用loop()来处理messages,直到循环终止。
大多数和message loop的交互是通过Handler。
下面是一个典型的带有Looper的线程实现。
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
publicvoidhandleMessage(Message msg) {
// processincomingmessages here
}
};
Looper.loop();
}
}
30、系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原由。
通过直接发送Uri把参数带过去,或者通过manifest里的intentfilter里的data属性
31、什么是ANR如何避免它?