也不是多大的问题,但是常用却容易混淆,都网络资源,整合了自己的语言,不明白的话 请参见原文
1.activity横竖屏切换生命周期
经实验,我认为网上大多数说法错误:
我的正确认知:1.横变竖,竖变橫activity都会被销毁一次创建一次(网上错误:橫变竖2次)
2.设置不变屏
activity中设置
android:screenOrientation="portrait"//竖屏
android:screenOrientation="<span style="font-size:14px;"><span style="font-family:verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif;line-height: 24px; background-color: rgb(255, 255, 255);">landscape</span></span>"// 横屏
3. 屏幕旋转时不重新走生命周期在mainfest中,三个都要配置否则可能出现无效的结果
android:configChanges="keyboardHidden|orientation|screenSize"
就只会走方法一次
onConfigurationChanged(Configuration newConfig)
2.数据库耗时的问题
数据库需要开关流。开关事物。如果把很多系数据操作,放入一个事物中,可以只开关一次io流,缩短时间
3.String和StringBuffer,StringBuilder的区别
String是final类,不可追加
后两者可以追加,StringBuffer线程安全(单线程或者说通过代码保护),可追加,较快
StringBuilder线程不安全(多线程),可追加,很快
4.android更新ui的主要方法(我觉得就是在主线程更新,或者说子线程如何更新ui,但是就是这么问)
1.利用Looper更新UI界面(就是handler)
2.AsyncTask利用线程任务异步更新UI界面
3.利用Runnable更新UI界面比如:Activity.runOnUiThread() 方法
5.堆和栈的区别
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。(int a= 3 ;int b = 3; a和b指向一致)
6.线程的5种状态
新建-就绪状态(无xpu)-阻塞状态(有cpu a.seelp b.被耗时阻塞如io读取 c.进入同步锁代码单被别人占用 d.等待某个触发条件)-运行状态(有cpu)-死亡状态
7.面向对象的三大特征:五大原则;
封装,继承,多态
五大基本原则
单一职责原则SRP(Single Responsibility Principle)
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。
开放封闭原则OCP(Open-Close Principle)
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,
那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。
替换原则(the Liskov Substitution Principle LSP)
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,
也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。
依赖原则(the Dependency Inversion Principle DIP) 具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,
这个时候,B不应当直接使用A中的具体类: 而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到
了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。
接口分离原则(the Interface Segregation Principle ISP)
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来
8.view刷新自己的方法
一组是invalidate 主线程调用
另一组是postInvalidate 子线程调用
9.线程同步的方法
1.同步方法
2.同步代码块
3.使用特殊域变量(volatile)实现线程同步 她是用来修饰变量的
4.a.使用重入锁实现线程同步ReentrantLock() : 创建一个ReentrantLock实例lock lock. lock() : 获得锁 lock.unlock() : 释放锁
b.ReentrantLock()还有一个可以创建公平锁的构造方法,但由于能大幅度降低程序运行效率,不推荐使用
10.int和Integer的区别
1。Ingeter是int的包装类
2.int的初值为0,Ingeter的初值为null。
3.int定义的是变量,Integer定义的是对象。 前者定义的值是存在栈中,后者在堆中
11.嵌入式
12.单元测试
13.跨进程通信
http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f7636d918d027fa3c215cc7902155a66e1b827201019d0c6776403ad5e5c9daa702d691765eadb9e871981edd27574de3034010bf63705a713b8bb4732b051875b99b86996ad873484afa2c4af5344bb55127bf0e7fa2c1767c07886162692a1&p=882a964fd18c13e007b8c7710f6490&newp=9b3bd3109c904ead08e297740a0083231610db2151d7d0156b82c825d7331b001c3bbfb423231006d8cf7b6602ae495feaf436783c0821a3dda5c91d9fb4c57479&user=baidu&fm=sc&query=android+%BD%F8%B3%CC%BC%E4%B5%C4%CD%A8%D0%C5&qid=ad5bdbd8000408f5&p1=1
4种方式 四个组件 活动(电话本) 广播 服务 内容提供者
14.intent 和intentfilter
http://blog.csdn.net/cnnumen/article/details/8464786
http://www.cnblogs.com/liushengjie/archive/2012/08/30/2663066.html
intent是在代码内部实现的,intentfilter通常是在mainfest里配置实现的
intent可以设置ComponentName 或者直接在构造方法里填入 new Intent(A.this,B.class);设置显式跳转
而隐式Intent则通过Intent中的action, category, data,查找mainfest中activity中的intenfilter的action, category, data来匹配跳转 优先级:action->data->category
常用action intent最多只能定义1个action, 而filter可以定义1个或多个action. 隐式跳转 intent定义的必须满足
ACTION_CALL--目标组件为activity, 代表拨号动作;
ACTION_EDIT--目标组件为activity, 代表向用户显示数据以供其编辑的动作;
ACTION_MAIN--目标组件为activity, 表示作为task中的初始activity启动;
ACTION_BATTERY_LOW--目标组件为broadcastReceiver, 提醒手机电量过低;
ACTION_SCREEN_ON--目标组件为broadcast, 表示开启屏幕.
Category属性 intent可以任意多个category, filter也可以任意个category. 隐式跳转 intent定义的多个必须满足
category属性也是一个字符串, 用于指定一些目标组件需要满足的额外条件. Intent对象中可以包含任意多个category属性. Intent类也预定义了一些category常量, 开发者也可以自定义category属性.
Intent类的addCategory()方法为Intent添加Category属性, getCategories()方法用于获取Intent中封装的所有category.
以下是Intent类中预定义的部分category:
CATEGORY_HOME--表示目标activity必须是一个显示home screen的activity; 隐式跳转 intent定义的必须满足
CATEGORY_LAUNCHER--表示目标activity可以作为task栈中的初始activity, 常与ACTION_MAIN配合使用;
CATEGORY_GADGET--表示目标activity可以被作为另一个activity的一部分嵌入.
Intent的Data属性 intent最多只能定义1个data, filter则可以定义多个data.
data属性指定所操作数据的URI. data经常与action配合使用, 如果action为ACTION_EDIT, data的值应该指明被编辑文档的URI; 如果
action为ACTION_CALL, data的值应该是一个以"tel:"开头并在其后附加号码的URI; 如果action为ACTION_VIEW, data的值应该是一个以"http: "开头并在其后附加网址的URI...
Intent类的setData()方法用于设置data属性, setType()方法用于设置data的MIME类型, setDataAndType()方法可以同时设定两者. 可以通过getData()方法获取data属性的值, 通过getType()方法获取data的MIME类型.
15.activity设置为窗口模式http://blog.csdn.net/zuo_0625/article/details/51325032
1.在AndroidManifest.xml清单配置文件中修改当前Activity的theme属性 可以在application中设置 也可以在activity‘中设置
android:theme="@style/Theme.AppCompat.Light.Dialog"
2.自定义style设置
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="Theme.FloatActivity" parent="Theme.AppCompat.Light.Dialog">
<item name="android:windowBackground">@drawable/float_box</item>
</style>
</resources>
自定义drawable中的
shape
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorAccent"/>
<stroke android:width="3dp" android:color="#000000"/>
<corners android:radius="5dp"/>
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp"/>
</shape>
16.输入框布局上移 http://www.cnblogs.com/CaptainLin/p/3835724.html
1.在代码中设置
在你的activity中的oncreate中setContentView之前写上这个代码getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
2.在mainfest中配置
在项目的AndroidManifest.xml文件中界面对应的<activity>里加入android:windowSoftInputMode="stateVisible|adjustResize",这样会让屏幕整体上移。如果加上的是
android:windowSoftInputMode="adjustPan"这样键盘就会覆盖屏幕。
3.在xml中配置
把顶级的layout替换成ScrollView,或者说在顶级的Layout上面再加一层ScrollView的封装。这样就会把软键盘和输入框一起滚动了,软键盘会一直处于底部
17.Thread.Runnable的区别
Thread
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
18.Service的使用,如何避免Service被杀死
service2启动方式 ,startService(intent) bindservice(intent)
前者会一直运行,直到 stopService(intent)或者在服务内部stopSelf(),stopSelf(int ); stopSelf(int)的意思是处理完所有的satrtService后才停止服务, 参数是startService的次数
后者与,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止onUnbind()方法解除调用者与服务解除
2. 如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
3. 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
4. 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。
保证不被杀死
第一种:
StartCommond几个常量参数简介:
1、START_STICKY
在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。
2、START_NOT_STICKY
在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。
3、START_REDELIVER_INTENT
在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
flags = START_STICKY;
return super.onStartCommand(intent, flags, startId);
}
结果手动返回START_STICKY,亲测当service因内存不足被kill,当内存又有的时候,service又被重新创建,比较不错,但是不能保证任何情况下都被重建,比如进程被干掉了....
第二种:
提升service优先级
在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。
<service
android:name="com.dbjtech.acbxt.waiqin.UploadService"
android:enabled="true" >
<intent-filter android:priority="1000" >
<action android:name="com.dbjtech.myservice" />
</intent-filter>
</service>
结论:目前看来,priority这个属性貌似只适用于broadcast,对于Service来说可能无效
第三种
Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收。Android将进程分为6个等级,它们按优先级顺序由高到低依次是:
1.前台进程( FOREGROUND_APP)
2.可视进程(VISIBLE_APP )
3. 次要服务进程(SECONDARY_SERVER )
4.后台进程 (HIDDEN_APP)
5.内容供应节点(CONTENT_PROVIDER)
6.空进程(EMPTY_APP)
当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,可以使用startForeground将service放到前台状态。这样在低内存时被kill的几率会低一些。
第四种
onDestroy方法里重启service
service +broadcast 方式,就是当service走ondestory的时候,发送一个自定义的广播,当收到广播的时候,重新启动service;
<receiver android:name="com.dbjtech.acbxt.waiqin.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.dbjtech.waiqin.destroy" />//这个就是自定义的action
</intent-filter>
</receiver>
在onDestroy时:
@Override
public void onDestroy() {
stopForeground(true);
Intent intent = new Intent("com.dbjtech.waiqin.destroy");
sendBroadcast(intent);
super.onDestroy();
}
在BootReceiver里
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.dbjtech.waiqin.destroy")) {
//TODO
//在这里写重新启动service的相关操作
startUploadService(context);
}
}
}
或者不用广播
也可以直接在onDestroy()里startService
@Override
public void onDestroy() {
Intent sevice = new Intent(this, MainService.class);
this.startService(sevice);
super.onDestroy();
}
第五种
Application加上Persistent属性
看Android的文档知道,当进程长期不活动,或系统需要资源时,会自动清理门户,杀死一些Service,和不可见的Activity等所在的进程。但是如果某个进程不想被杀死(如数据缓存进程,或状态监控进程,或远程服务进程),可以这么做:
<application
android:name="com.test.Application"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
<span style="color:#ff0000;"> android:persistent="true"</span>
android:theme="@style/AppTheme" >
</application>
第六种
开两个服务,互相监视
19.内存的管理
尽可能少的使用服务,或者使用Intentservice,保证服务的准确性
使用优化过的代码代替存储hashmap用 SparseArray替代
避免枚举
避免注解
第三方库要小心
bitmap即使释放资源 查询数据库及时关闭 避免静态 避免全局 adapter优化 context尽量 application的context
线程的优化:
ui的优化: