1、什么是ANR以及如何避免它?
答:在android中,由活动管理器(ActivityManager)和窗口管理器(WindowManager)来监听系统服务的响应,如果一个应用程序出现长时间无响应输入事件的状态,系统会弹出一个对话框提示应用程序无响应,提示用户是否继续等待还是退出,这种情况通常称为ANR(Application Not Responsing)。 一般情况下,应用程序无响应的时间超过5秒会出现ANR,而BroadcastReceiver超过10秒才会出现。
ANR一般是由于在主线程中执行过多的耗时操作比如数据库操作、网络服务,以及复杂的逻辑运算等等造成的。所以应开启子线程,利用Handler以及Message来处理这些操作,比如更新UI,也可以利用runOnUiThread来将子线程切换到主线程。

2、Android四大组件及生命周期?
答:四大组件分别是Activity、BroadcastReceiver、Service和Content Provider。
(1)Activity(活动):用于和用户进行交互的界面,在这个界面中可以通过控件来监听和处理一些用户输入事件(点击、触摸、滑动等)。当一个活动A第一次启动时,会依次调用onCreate()方法,onStart()方法和onResume()方法,当A利用Intent启动一个新的活动B时,如果B是一个窗体或透明型使得A仍然可见则A会调用onPause()方法,若A不可见则会调用onStop()方法,此时重新启动A会调用onRestart()方法,当A被销毁时会调用onDestroy()方法。

(2)BroadcastReceiver(广播接收器):用于接收来自系统或其他应用程序发送的广播,其注册有两种方式,一种是在代码中动态注册,一种是在manifest静态注册.
Activity中注册:

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

manifest中注册:

<Receiver android:name=".Myreceiver">    <Intent-Filter>        <action android:name="android,intent.action.MY_RECEIVER"/>    Intent-Filter>Receiver>

BroadcastReceiver的生命周期很短,当接收到一个广播时会调用onReceive()方法,下面是API文档的解释,可以看到不能再这个方法中进行耗时操作,因为系统仅允许其在10秒之内接收广播,否则请求会被杀死。

When it runs on the main thread you should never perform long-running operations in it (there is a timeout of 10 seconds that the system allows before considering the receiver to be blocked and a candidate to be killed). You cannot launch a popup dialog in your implementation of onReceive().

(3)Service(服务):与Activity相同的级别,区别是Service用于长时间运行而不需要和用户直接交互或被其他应用程序使用,使用时必须在manifest中注册。Service也有两种启动方式startService()和bindService(),第一种启动后必须调用stopSelf()方法进行取消,或在启动之后可调用stopService();第二种用于将Activity或其他组件与Service绑定,可以使用IBinder接口与ServiceConnection来进行绑定。

Service的生命周期有两种形式,一种是通过context.startService()启动然后调用onCreate()方法和onStartCommand()方法,其中onCreate()只在第一次调用startService()时执行,最后调用stopSelf()或context.stopSevice()后Service的onDestroy()方法执行然后服务销毁。第二种是客户端可以通过context.bindService()来与服务建立一个永久的连接,当Service的onCreate()并未执行时,同样也可以创建Service,不过此时会执行onBind()方法,从而返回一个IBinder对象给客服端,允许客户端调用回服务,服务会一直运行只要建立连接并且没有断开,如果此时既调用了onStart()又调用了bindService(),Android中规定必须使得两种条件都不满足才能销毁服务,所以要同时调用stopService()和unbindService()再能使onDestroy()方法执行,服务才会销毁,完成最后的清理工作(停止线程、取消服务的注册等等)。

(4)ContentProvider(内容提供器):用于不同应用程序之间实现数据共享的功能,并且保证数据的安全性。这些数据可以使用文件、sharePreference或SQLite数据库进行存储。
使用ContentProvider会实现6个抽象方法,分别是onCreate(),query(),insert(),update(),delete(),getType().使用这些方法对数据进行增删改查操作。

3、Activity的四种启动模式?
答:standard、singleTop、singleTask、singleInstance。
(1)standard:默认的启动模式。在这种模式下,每当启动一个新的活动就会在返回栈中入栈,并处于栈顶位置,无论是否栈中已存在该活动,启动时都会创建一个实例。
(2)singleTop:当启动活动时发现栈顶已是该活动,则不再创建新的实例,若并未位于栈顶启动时仍会创建实例。
(3)singleTask:每次启动活动时系统会在返回栈中检查是否存在该活动的实例,如果有直接使用,并把这个活动上面所有活动出栈。
(4)singleInstance:在这种模式下,系统开始会检查是否存在目标Activity的实例,如果已存在,直接将其所在的Task转到前台,然后显示这个Activity;如果目标Activity不存在,则会创建一个新的Task,再创建一个目标Activity实例放入栈顶,无论是哪种情况,加载的活动都位于栈顶且Task中只有这一个活动。

4、Activity界面恢复与保存?
答:当手机的内存不足时,系统会销毁一些在后台运行的活动,此时如果重新启动这个活动,可能刚在正在进行的任务或处理的数据会消失,Android中提供了一种方法onSaveInstanceState()和RestoreInsatanceState()用来保存数据和重新获取数据,当系统要毁掉一个活动时,会调用onSaveInstanceState()方法,而这个方法会使用一个Bundle对象来保存数据,最后调用RestoreInstanceState()方法进行取数据,而且在Activity中的onCreate(Bundle savedInstanceState)方法的参数中也可以获取数据。

5、DDMS与traceView的区别?
答:DDMS是一个程序执行查看器,在其内可以看到一些线程和堆栈信息,可用于检测内存是否泄漏。
traceView是一个程序性能分析器,可用来跟踪代码执行的时间,在要跟踪的两个方法中分别添加Debug.startMethodTracing();和 Debug.stopMethodTracing();并在注册文件生命SD卡写权限,然后进行编译运行程序, 最后使用shell导出在SD卡中生成的trace文件,打开后可进行分析代码各处的耗时情况。

6、什么是AIDL以及如何使用?
答:AIDL( Android Interface definition language)服务是一种android内部进程通信接口的描述语言,通过它可以定义进程中的通信接口,从而实现跨进程访问。
AIDL服务建立的步骤如下:
(1)在Android Studio的工程下的app文件new一个aidl文件,该文件的语法类似于Java代码,不过不能加任何修饰符,AIDL不支持的数据类型(InputStream、OutputStream等等)。

在这里新建一个MyService.aidl文件,并且写入一个String方法。

// MyService.aidlpackage com.example.asus.aidl;// Declare any non-default types here with import statementsinterface MyService {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.    */     String getValue();}

(2)如果aidl文件的内容是正确的,ADT会自动编译并且生成一个Java接口文件(*.java),位置如下图所示。

(3)建立一个TestService类(Service的子类),在该类中新建一个TestServiceImpl类继承Myservice.Stub类,然后在TestServiceImpl类中实现接口中的方法,并且在onBind()方法中返回TestServiceImpl的实例,否则客户端无法获得服务对象。

package com.example.asus.aidl;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;/** * Created by asus on 2017/3/17. */public class TestService extends Service {    public class TestServiceImpl extends MyService.Stub{        @Override        public String getValue() throws RemoteException {            return "Hello World";        }    }    @Nullable    @Override    public IBinder onBind(Intent intent) {        return new TestServiceImpl();    }}

(5)在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。

<service android:name=".TestService">    <intent-filter>        <action android:name="com.example.wk.aidl.MyService"/>    intent-filter>service>

其中”com.example.wk.aidl.MyService”是客户端访问AIDL服务的id。
(6)当服务端得到AIDL服务时,然后要在客户端绑定服务,首先新建一个工程用于客户端测试,把刚才的工程下的app/src/main目录下系统自动创建的aidl文件夹连同底下的包以及adil文件一起复制到新的工程的app/src/main目录下(一定要复制过去,如果新建即使命名相同可能也会编译失败)如图所示:

(7)新建一个类TestAdilClient用于绑定服务,定义两个Button,第二个先设为不可用,点击第一个Button会调用bindService()方法进行绑定,如果绑定成功会调用onServiceConnected()方法将服务端获取的IBinder对象传给客户端,第二个调用服务的Button会变为可用状态,然后点击调用服务端的getValue()方法获取一个字符串。

package com.example.asus.aidl;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.TextView;public class TestAidlClient extends AppCompatActivity implements View.OnClickListener {    private Button bind_service;    private Button send;    private TextView content;    private MyService myService;    private ServiceConnection connection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            myService = MyService.Stub.asInterface(service);  //将服务端的IBinder对象传给客户端            send.setEnabled(true);        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        bind_service = (Button)findViewById(R.id.bind_Service);        send = (Button)findViewById(R.id.send);        send.setEnabled(false);        content = (TextView)findViewById(R.id.content);        bind_service.setOnClickListener(this);        send.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch(v.getId()){            case R.id.bind_Service:                Intent intent = new Intent();                intent.setAction("com.example.wk.aidl.MyService");                intent.setPackage("com.example.asus.aidl");                bindService(intent,connection, Context.BIND_AUTO_CREATE);                break;            case R.id.send:                try{                    content.setText(myService.getValue());                }catch (RemoteException e){                    e.printStackTrace();                }                break;        }    }}

在这里要注意的一点是在android5.0以上的版本在发送服务时不能使用隐式Intent,因此在创建一个Intent对象后不仅要添加action还要添加要访问app的包名。

intent.setAction("com.example.wk.aidl.MyService");intent.setPackage("com.example.asus.aidl");

这样一个简单的AIDL服务通信就完成了,下面是调试结果:

更多相关文章

  1. Android(安卓)proguard混淆编译的问题
  2. Android反编译工具介绍
  3. 阅读《Android(安卓)从入门到精通》(3)——Activity 与界面
  4. Launcher桌面点击&长按&拖动事件处理流程分析
  5. Android:BottomNavigationView设置noActionbar主题后闪退的解决方
  6. Android.mk详解
  7. Android(安卓)Studio开发Groovy
  8. android:webView总结
  9. Android(安卓)Studio快捷键汇总

随机推荐

  1. Android开发中完全退出程序的三种方法
  2. Android:sharedUserId介绍
  3. 绕过身份检测,破解Android(安卓)SU
  4. Android(安卓)VideoView 循环播放视频
  5. Android(安卓)TVBox开发:logcat常用命令,四
  6. Android(安卓)判断App运行在模拟器还是真
  7. Android(安卓)学习项目开发案例
  8. [置顶] Android(安卓)设置铃声分析
  9. android : 修改frameworks/base/ 代码需
  10. Android(安卓)retrofit2+OkHttp3的初尝试