您的位置:首页 > 移动开发 > Android开发

Android Interview Collection

2016-03-16 15:48 537 查看
1、如何有效的处理未捕获的异常

继承自UncaughtExceptionHandler类,然后调用重载uncaughtException(Thread thread, Throwable ex)函数,还可以将日志写文件存储到SD卡,发送给服务器。

2、数据存储方式

1)SharePrefrences

怎样提供一个公共的setData()方法和一个getData()方法?

2)文件存储

3)SQLite数据库存储

4)ContentProvider存储

ContentProvider所提供的函数:query(),insert(),update(),delete(),getType(),onCreate()等。
URI构成:content://包 . 类的名称/数据库中表的名字/数据id

eg. content://hx.android.text.myprovider/tablename/222

5)网络存储

3、Intent怎么传递对象或者数组

Android中Intent传递类对象有两种方式,一种是通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象。

Bundle b = new Bundle();

b.putSerializable("item", info);

i.putExtra("bundle", b);

// 获取

Bundle b = i.getBundleExtra("bundle");

mHouseInfo = (HouseInfo) b.getSerializable("item");

4、Android
Looper和Handler


Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消 息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该 线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。 如下例所示:

class LooperThread extends Thread {

public Handler mHandler;

public void run() {

Looper.prepare();

mHandler = new Handler() {

public void handleMessage(Message msg) {

// process incoming messages here

}

};

Looper.loop();

}

}

使线程拥有自己的消息列队,主线程拥有自己的消息列队,一般线程创建时没有自己的消息列队,消息处理时就在主线程中完成,如果线程中使用Looper.prepare()和Looper.loop()创建了消息队列就可以让消息处理在该线程中完成

5、Activity的生命周期



6、你后台的Activity被系统回收怎么办:onSaveInstanceState

当你的程序中某一个Activity A 在运行时中,主动或被动地运行另一个新的Activity B,这个时候A会执行

void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putLong("id", 1234567890);

}

7、Animations简介

Animations从总体上可以分为两大类:

1.Tweened Animations(渐变动画):

   1) AlphaAnimation:淡入淡出效果

   2) ScaleAnimation:缩放效果

   3) RotateAnimation:旋转效果

   4) TranslateAnimation:移动效果

2.Frame-by-frame Animations(帧动画):

帧动画创建一个Drawable序列,这些Drawable可以按照指定的时间间歇一个一个的显示。  

Frame-By-Frame Animations的使用方法

<?xmlversion="1.0"encoding="utf-8"?>

<animation-list xmlns:android=http://schemas.android.com/apk/res/android android:oneshot="false">

<itemandroid:drawable="@drawable/a_01"android:duration="50"/>

<itemandroid:drawable="@drawable/a_02"android:duration="50"/>

<itemandroid:drawable="@drawable/a_03"android:duration="50"/>

</animation-list>

AnimationListener主要包括如下三个方法:

·onAnimationEnd(Animation animation) -当动画结束时调用

·onAnimationRepeat(Animation animation) -当动画重复时调用

·onAniamtionStart(Animation animation) -当动画启动时调用

8、请介绍下Android中常用的几种布局

1、 LinearLayout – 线性布局。

2、 AbsoluteLayout – 绝对布局。

3、 TableLayout – 表格式布局

表格布局主要以行列的形式来管理子控件,其中每一行即一个TableRow对象,每个TableRow对象可以添加子控件,并且每加入一个控件即相当于添加了一列

4、 RelativeLayout – 相对布局。

5、 FrameLayout – 层叠布局。以左上角为起点,将 FrameLayout 内的元素一层覆盖一层地显示,在帧布局中,先添加的图片会被后添加的图片覆盖。

9、如何启用Service,如何停用Service。

1.通过调用Context.startService()启动,调用Context.stopService()结束,startService()可以传递参数给Service

2.通过调用Context.bindService()启动,调用Context.unbindservice()结束,还可通过ServiceConnection访问Service。

3. adb启动service

$ adb shell

$ am startservice -n {包(package)名}/{包名}.{服务(service)名称}

如:启动自己应用中一个service

# am startservice -n com.android.traffic/com.android.traffic.maniservice

在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

10、如何加载网络图片?

单启一个线程,用HttpClient去下载图片,然后存储到软引用和SD卡或者手机内存(具体地址呢?),下次首先判断软引用,再判断SD,都没有则重新下载。

11、AIDL的是什么?

当A进程要去调用B进程中的service时,并实现通信,我们通常都是通过AIDL来操作的

Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote
Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition
Language)服务。

12、注册广播有几种方式,这些方式有何优缺点?

两种注册类型的区别是:

1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。

2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

13、Android不同分辨率适配?dip、dpi、px之间的关系?(1 英寸 = 2.54 厘米)

1. dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关。

2. dpi:dots per inch(像素密度)(单位:像素/英寸),表示屏幕每英寸有多少个像素

dip =(dpi/160)* pixel

float density = context.getResources().getDisplayMetrics().density (指的就是dpi/160)

比如4英寸、854×480的分辨率,那么dpi就是854的平方加480的平方和开2次方后除以4,结果大约是245,为hdpi。

3. px: pixels(像素),不同的设备不同的显示屏显示效果是相同的,这是绝对像素,不会改变。

===============================================================

120 (ldpi) 低密度 (240*320) (1dip=0.75px)

160 (mdpi) 中密度 (320*480) (1dip=1px)

240 (hdpi) 高密度 (480*800) (1dip=1.5px)

320 (xdpi) 超高密度 (720*1280) (1dip=2px)

480 (xxdpi) 超清密度 (1080*1920) (1dip=3px)

===============================================================

14、环形进度条怎么实现,自定义View怎么添加属性?

自定义View,onDraw里面调用

canvas.drawArc(oval, float startAngle, float sweepAngle, boolean useCenter,paint)

canvas.drawCircle(cx, cy, radius, paint)

添加属性:attrs.xml里面声明<declare-styleable name="ProgressWheelView">

15、描述一下Android的系统架构

Android系统架构分从下往上为 Linux内核层、系统运行库层、应用程序框架层、和应用程序层。

16、Activity和Task的启动模式有哪些? 每种含义是什么?

Android定义了4种activity的启动模式:standard(默认)、singleTop、singleTask、singleInstance

17、ScrollView中嵌套ViewPager、Listview时,滑动不灵敏问题

class YScrollDetector extends SimpleOnGestureListener {

@Override

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

if (Math.abs(distanceY) >= Math.abs(distanceX) + 20) {

return true;

}

return false;

}

}

18、如何实现广告位?(后台配置数据)

viewpager+webview+javaScript+html5(Android和html5的交互)

19、点击时背景和字体变色?

android:background="@drawable/joblecture_item_selector"

android:textColor="@drawable/selector_job_lecture"

20、Android 在子线程中更新UI有几种方法

1、post()和postDelay()

new Handler(context.getMainLooper()).post(new Runnable() {

@Override
public void run() {
// 在这里执行你要想的操作 比如直接在这里更新ui或者调用回调在 在回调中更新ui

}
});


2、runOnUiThread()

// 如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程
// 因为runOnUiThread是Activity中的方法,Context是它的父类,所以要转换成Activity对象才能使用
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
// 在这里执行你要想的操作 比如直接在这里更新ui或者调用回调在 在回调中更新ui
}
});


3、Handler + Message或者Handler + Thread + Message

主线程建立时,默认情况下是有Looper的,可以处理消息队列。

在主线程建立一个Handler对象,复写其handleMessage()方法,在该方法中实现UI更新。

示例:

private static final int MSG_CODE = 1001;
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg){
//接收并处理消息
if(msg.what == MSG_CODE){
//UI更新
}
}
};
public void doSomething(){
new Thread(){
@Override
public void run(){
//子线程发送信息
Message msg = mHandler.obtainMessage(MSG_CODE);
msg.sendToTarget();
}
}.start();
}


4、Broadcast

子线程中发送广播,主线程中接收广播并更新UI

5、AsyncTask
AsyncTask可方便地实现新开一个线程,并将结果返回给UI线程,而不需要开发者手动去新开一个线程,也无须开发者使用Handler,非常方便。

应当注意的是AsyncTask是一个抽象类,其三个泛型参数的意义如下:

AsyncTask<Param, Progress, Result>

Param:发送给新开的线程的参数类型

Progress:表征任务处理进度的类型。

Result:线程任务处理完之后,返回给UI线程的值的类型。

该类中有四个抽象函数,onPreExecute(), doInBackground(Params... param),

onProgressUpdate(Progress... progress), onPostExecute(Result result)。

除了,doInBackground(Params...)方法,其它三个方法都运行在UI线程。

自定义一个类继承AsyncTask并至少实现doInBackground()函数。在该函数中执行的过程中,可以随时调用publishProgress(Progress...)报告其执行进度。此时会触发另一个方法onProgressUpdate(Progress... progress),以便在UI线程中的某些控件(如ProgressBar)上更新任务处理的进度。

也可以等doInBackground()执行完,进入onPostExecute()方法后,再进行UI控件的更新。

可在任意时间,任意线程中,取消AsyncTask开启的任务(调用自定义的AsynTask子类的cancel(boolean mayInterruptIfRunning)方法)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: