1、JAVA中final、finally、finalize的区别
① final:关键字,可以作为修饰符修饰变量、方法和类,被final修饰的变量只能一次赋值;被final修饰的方法不能够在子类中被重写(override);被final修饰的类不能够被继承
② finally用在异常处理中定义重视执行代码,无论try块中的代码是否引发异常,catch是否匹配成功,finally块中的代码总是被执行,除非JVM被关闭(System.exit()),通常用作释放外部资源(不会被垃圾回收器回收的资源)
③ finalize()方法是Object类中定义的方法,当垃圾回收器将无用对象从内存中清除时,该对象的finalize()方法被调用,由于该方法是protected方法,子类可以通过重写(override)该方法以整理资源或者执行其他的清理工作
2、UI中,padding和margin的区别
① padding为内边框,指该控件内部内容
② margin为外边框,指该控件距离边,父控件的距离
设置padding的好处:如果imageView对应的图片比较小,点击不容易点中,通过增加padding可以增大点触敏感度
3、常见的指引标注
500:服务器内部错误,主要是由于WAN账号的密码错误造成的
404:资源找不到
200:连接成功
4、JAVA冒泡排序法
冒泡排序法算法运作如下:
1)比较相邻的元素。如果第一个比第二个大,就交换他们两个
2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数
3)针对所有的元素重复以上的步骤,除了最后一个。
4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一个数字需要比较。
public class Bubble{
public static void main(String[] args){
int score[] = {1 , 7 , 9 , 30 , 40 , 23 , 56 , 15};
//最多做n-1次排序
for(int i = 0; i < score.length - 1 ; i++){
//对当前无序区间score进行排序,(j的范围是逐步缩小的)
for(int j = 0; j < score.length - i - 1; j++){
//把小的值交换到后面
if(score[j] < score[j + 1]){
int temp = score[j];
score[j] = score[j + 1];
score[j + 1] = temp;
}
}
System.out.print("第" + (i + 1) + "次排序的结果是:");
for(int a = 0; a < score.length; a++){
System.out.print(score[a] + "");
}
System.out.println("");
}
System.out.println("最终排序的结果是:");
for(int a = 0; a < score.length; a++){
System.out.println(score[a]);
}
}
}
5、Activity的生命周期
![](https://img.haomeiwen.com/i7342844/6bb8af555f71d9e8.png)
6、HTTP中GET和POST的区别
GET是服务器上获取数据
POST是向服务器传送数据
GET是把参数数据队列加到提交表单的action属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到
POST是通过HTTP POST机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到action属性所指的URL地址
对于GET方式,服务器端用Request.QueryString获取变量的值
对于POST方式,服务器端用Request.Form获取提交数据
GET传送的数据量较小,不能大于2KB
POST传送的数据量较大,一般被默认为不受限制,但理论上,IIS4中最大为80KB,IIS5中最大为100KB
GET安全性非常低
POST安全性比较高
7、内存泄露的原因及解决方法(OOM)
定义:当某些对象不再被程序所使用,但是这些对象仍然被某些对象所引用,进而导致垃圾收集器不能及时释放它们。(无效的对象没有及时回收,导致内存不够用,致使程序出错)
① 内部类(handler等):当线程执行耗时任务时,即便Activity已经销毁,但是其实例未必被垃圾回收器及时回收,进而导致内存泄漏。
解决方法:在依附于的那个类销毁的时候自己也销毁,就类似于Activity销毁了,什么Thread、Dialog、Handler全部关闭掉
② 大量位图的加载
//解决方法
inJustDecodeBounds = true;
BitmapFactory.Options();
③ Bitmap对象在不调用的时候
//解决方法:Bitmap.recycle();
if(bitmap != null && bitmap.isRecycled){
bitmap.recycle();
bitmap = null;
}
④ 查询数据库没有关闭游标
解决方法:cursor.close();
⑤ 构造Adapter时,没有使用缓存的convertView(现在已经改用RecyclerView)会造成内存溢出的代码
public View getView(int position, View convertView, ViewGroup parent){
View view = new View();
XXX XXX
return view;
}
//修正后的代码
public View getView(int position, View convertView, ViewGroup parent){
if(convertView == null){
convertView = new View();
XXX XXX
}else{
XXX XXX
}
}
8、Android软引用和弱引用的区别
1)软引用(SoftReference<T>) 当内存不足的时候,将会回收它指向的对象,需要获取对象时,可以调用get方法,(软引用在内存严重不足的情况下会被系统回收)
2)弱引用(WeakReference<T>) 随时可能被垃圾回收器回收,不一定要等到内存不足的时候才强制回收,要获取对象可调用get方法(在系统内存出现报警<比严重不足的程度低>情况下回收)
3)弱引用一般用来防止内存泄漏,要保证内存被虚拟机回收
4)软引用多用来实现缓存机制(Cache)
9、常用的数据存储方式
1)使用SharedPreferences存储数据
2)文件存储数据(IO流写入、读取数据)
3)SQLite数据库存储数据
4)使用ContentProvider存储数据
5)网络存储数据(HttpUrlConnection)
10、异步处理的方式
1)首先写一个AsyncQueryHandler类
2)然后new一个对象。查询完后回调onQueryComplete
//① 对数据库URI查询的异步方式 --- AsyncQueryHandler
private final class QueryHandler extends AsyncQueryHandler{
public QueryHandler(ContentResolver content){
super (content);
}
protected void onQueryComplete(int token,Object cookie,Cursor cursor){
super.onQueryComplete(token,cookie,cursor);
//更新mAdapter的cursor
mAdapter.changCursor(cursor);
}
}
/**
*② 使用Thread+Handler实现非UI线程更新UI界面
*③ 使用AsyncTask异步更新UI界面
*/
11、基本的加载网络图片的方式
1)普通加载网络方式 (setImageBitmap)
2)用 ImageLoader 加载图片
3)用 Volley 加载图片
12、Fragment生命周期
![](https://img.haomeiwen.com/i7342844/09adb6f648b7b861.png)
13、利用JDBC连接数据库
1、直接连接<安全性不高,一旦访问数量过多容易出现问题>
在Android工程中引入JDBC驱动,直接连接
加载JDBC驱动 ---> 建立连接 ---> 发送SQL语句
1)在Android工程中使用JDBC,需要导入JDBC的驱动
2)发送SQL语句之前,要创建一个statement对象,statement主要工作是把SQL语句发送给DBMS
3)需要加入连接网络的权限
2、间接连接<实用性和安全性都提高了>
在服务器上用PHP+DBMS做服务器端,PHP将DBMS中的数据用 JSON 或者XML 进行封装,然后再发封装好的数据返回给Android平台
14、屏幕适配的几种常用方法(如何解决屏幕适配的问题)
1、图片适配<该方法不常用>
原因:当图片在不同屏幕的手机上出现偏差、失帧等情况
解决方法:让UI多切几套图,放在res目录下的drawable对应不同的屏幕,当不同屏幕启动APP的时候会有权限访问其对应的目录下的图片资源,如果对应下面没有才会去访问其他的目录
2、布局适配<该方法不常用>
原因:当屏幕上同一个布局文件不能满足需求,比如大屏幕需要做特殊适配这种
解决方法:在res目录下新建一个文件夹,layout-800x480(适配800x480的屏幕,其他屏幕用同样的方法即可),然后在里面去进行指定的布局设置文件
3、尺寸适配
设备密度(dp和px的转换关系:dp=px/设备密度)
320x240(0.75),480x800(1.5),1280x720(2)这是主流几大屏幕对应的设备密度
//dp与px直接转换工具类
public class ScreenSizeAdapter {
/**
* dip转为 px
*/
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
/**
* px 转为 dip
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
4、权重适配
线性布局才能够设置权重
在LinearLayout属性设置里面可以设置总权重Android:weightSum;然后在里面的空间去分配权重,这样不管什么手机,都是按照权重比例去进行显示的
5、代码适配
代码适配类似于权重适配,权重适配可以通过代码适配来实现,但是代码适配不一定能够用权重适配来实现,比如相对布局不能用权重,就可以用代码来控制,实现原理是:计算屏幕宽高,动态的来设置空间宽高
![](https://img.haomeiwen.com/i7342844/059a65559e2b7e6e.png)
15、View分发事件是如何进行的
public boolean dispathTouchEvent(MotionEvent ev)
View / ViewGroup处理事件分发的发起者,接收到触控事件最先调起的就是这个方法,然后在该方法中判断是否处理拦截或是将事件分发给子容器
public boolean onInterceptTouchEvent(MotionEvent ev)
ViewGroup专用,通过该方法可以达到控件事件的分发方向,一般可以在该方法中判断将事件给ViewGroup独吞或是它继续传递给子容器,是处理事件冲突的最佳地点
public boolean onTouchEvent(MotionEvent ev)
触控事件的真正处理者,最后每个事件都会在这里被处理
16、列出Activity所有的启动模式,并简述各自的特点
1、standard 标准模式:
每次启动一个Activity都会重新创建一个实例,即调用Activity创建时的生命周期方法onCreate()、onStart()、onResume();被启动的Activity会自动添加到启动它的Activity的任务栈中,因此用ApplicationContext启动standard模式的Activity时会报错(Context没有所谓的任务栈)
2、singleTop 栈顶复用模式:
新启动的Activity已经位于任务栈的栈顶,那么此Activity将不会被重建,而是会回调其onNewIntent方法,如果新启动的Activity不是位于栈顶,此时将重新创建新的Activity实例并添加到栈顶
3、singleTask 内复用模式:
这是一种简单的单例模式,这种模式下只要被启动的Activity位于栈内,那么无论它是否位于栈顶都不会重新创建新的Activity实例,而是直接将其回调到栈顶并回调其onNewIntent方法,如果在其上有其他Activity的时候会将这些Activity进行出栈处理
4、singleInstance 单实例模式
这是一种加强的singTask模式,除了具有singleTask的特点外还加了一点,具体此模式的Activity会单独处于一个独立的任务栈,如Activity为singleInstance启动模式,当A启动后,系统会单独为其建一个任务栈,A将独自位于这个任务栈中,以后的请求均不会创建新的Activity直至这个任务栈被销毁
17、如何用一个非Activity的context去启动一个新的Activity
我们在日常开发中有时会遇到启动一个目标Activity的时候,会利用一个非Activity类型的Context去启动
Intent intent = new Intent(context,MainActivity.class);
conetext.startActivity(intent);
但是这样直接去启动一个目标Activity是不可以的,常会报下列异常:
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
这个异常的意思是:
启动一个目标Activity的context是非Activity类型,如果想要正确启动需要设置TAG Task,即FLAG_ACTIVITY_NEW_TASK。其实,意思是,如果我们想要启动一个Activity,启动它的context必须要有一个任务栈
//所以正确的做法应该是:
Intent inten = new Intent(context,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
18、如何快速地在JAVA中进行全局异常捕获
//捕获所有程序为直接处理的,由虚拟机抛出的异常
Thread.setDefaultUncaughtException()
//捕获该线程中抛出的程序本身未处理的异常
Thread thread = new Thread();
thread.setUncaughtException();
这两种方法中如果抛出了新的异常则会被JVM忽略
网友评论