Android面试题(三)

来源:互联网 发布:域名注册机构 编辑:程序博客网 时间:2024/06/05 15:31

1**1andriod mvp与mvc的区别**
m(view) 绘制ui,与用户的交互。
model:对数据的操作、对网络等的操作,和业务相关的逻辑处理;
presenter:Presenter理解为一个中间层的角色,它接受Model层的数据,并且处理之后传递给View层,还需要处理View层的用户交互等操作。
最大的区别就是mvp中model层不能和view层进行直接的交互,mvc中可以的。
2ScrollView嵌套ListView会出现的问题
出现的问题:
1listview只显示一条:
原因:ScrollView的重写了measureChildWithMargins方法导致它的子View的高度被强制设置成了MeasureSpec.UNSPECIFIED模式。简单的说就是ListView在计算(比较正式的说法是:测量)自己的高度时对MeasureSpec.UNSPECIFIED这个模式在测量时只会返回一个List Item的高度(当然还有一些padding这些的值我们可以先忽略)。
2listview 的滑动时间会消失
原因:从ScrollView的源码可以看到它对Touch事件(ACTION_MOVE)进行了拦截,所以滑动的事件传递不到ListView。
解决方案:

public class MyListView extends ListView {    public MyListView(Context context) {        super(context);    }    public MyListView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(480, // 固定高度(实际中这个值应该是根据手机屏幕计算出来的)                MeasureSpec.AT_MOST);        super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:            case MotionEvent.ACTION_MOVE:                getParent().requestDisallowInterceptTouchEvent(true);                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                getParent().requestDisallowInterceptTouchEvent(false);                break;        }        return super.onInterceptTouchEvent(ev);    }}

3Android application的oncreate有时会执行两遍,原因?
这样的情况可以检查一下AndroidManifest.xml是否给某个组件配置了android:process属性。每个进程创建后,都会启动一个主线程(Looper接收消息),每个组件启动前都会先创建Application实例(一个进程只创建一个)。

4线程安全是什么意思?
线程安全:多个线程操作同一段代码,不会出现未预期的结果。
关于线程安全理解有深入了。线程间的资源共享会让 UI 更新混乱(如果同时有两个线程更新 UI,是这个线程先更新呢,还是另外一个先更新),而强制规定必须在 UI 线程更新 UI 的话就要走 Handler 通信,这套通知机制是使用队列来进行,也就会有先来后到(不过这里面是如何确认先来后到的是不需要开发者了解的?),也就保证了 UI 更新正确性。

5 对Android 中BroadcastReceiver的理解。
(参考==========http://blog.csdn.net/liuhe688/article/details/6955668)
BroadcastReceiver: 广播接受者。
使用方法:

第一步:创建

package com.scott.receiver;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.util.Log;public class MyReceiver extends BroadcastReceiver {    private static final String TAG = "MyReceiver";    @Override    public void onReceive(Context context, Intent intent) {        String msg = intent.getStringExtra("msg");        Log.i(TAG, msg);    }}

第二步:注册
静态注册(常驻)
静态注册是在AndroidManifest.xml文件中配置的,我们就来为MyReceiver注册一个广播地址:

<receiver android:name=".MyReceiver">              <intent-filter>                  <action android:name="android.intent.action.MY_BROADCAST"/>                  <category android:name="android.intent.category.DEFAULT" />              </intent-filter>          </receiver>  

配置了以上信息之后,只要是android.intent.action.MY_BROADCAST这个地址的广播,MyReceiver都能够接收的到。注意,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,MyReceiver也会被系统调用而自动运行。
动态注册:(切记解除注册)
动态注册需要在代码中动态的指定广播地址并注册,通常我们是在Activity或Service注册一个广播,下面我们就来看一下注册的代码:

MyReceiver receiver = new MyReceiver();         IntentFilter filter = new IntentFilter();  filter.addAction("android.intent.action.MY_BROADCAST");       registerReceiver(receiver, filter);  

注意,registerReceiver是android.content.ContextWrapper类中的方法,Activity和Service都继承了ContextWrapper,所以可以直接调用。在实际应用中,我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。所以,记得在特定的地方执行解除注册操作:

@Override  protected void onDestroy() {      super.onDestroy();      unregisterReceiver(receiver);  }  

6广播的两种类型?区别?
无序广播:普通广播对于多个接收者来说是完全异步的,通常每个接收者都无需等待即可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法终止广播,即无法阻止其他接收者的接收动作。
有序广播:有序广播比较特殊,它每次只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者有能力终止这个广播。

有序广播接收这

public class FirstReceiver extends BroadcastReceiver {        private static final String TAG = "OrderedBroadcast";      @Override      public void onReceive(Context context, Intent intent) {          String msg = intent.getStringExtra("msg");          Log.i(TAG, "FirstReceiver: " + msg);          Bundle bundle = new Bundle();          bundle.putString("msg", msg + "@FirstReceiver");          setResultExtras(bundle);      }  }  <receiver android:name=".FirstReceiver">      <intent-filter android:priority="1000">          <action android:name="android.intent.action.MY_BROADCAST"/>          <category android:name="android.intent.category.DEFAULT" />      </intent-filter>  </receiver>  

android:priority 值得范围-1000–1000(值越大等级越大)

7广播常用的场景?
A 开启启动一个服务
B 检测网络
C检测电池的电量

0 0
原创粉丝点击