Android面试题(三)

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检测电池的电量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值