Android面试题:Service


1. Service是否在main thread中执行, service里面是否能执行耗时的操作?

默认情况,如果没有显示的指servic所运行的进程, Service和activity是运行在当前app所在进程的main thread(UI主线程)里面。

service里面不能执行耗时的操作(网络请求,拷贝数据库,大文件)。

特殊情况 ,可以在清单文件配置 service 执行所在的进程,让service在另外的进程中执行。

<service
    android:name="com.baidu.location.f"
    android:enabled="true"
    android:process=":remote" >
</service>

2. Activity怎么和Service绑定,怎么在Activity中启动自己对应的Service?

Activity通过bindService(Intent service, ServiceConnection conn,int flags)跟Service进行绑定,当绑定成功的时候Service会将代理对象通过回调的形式传给conn,这样我们就拿到了Service提供的服务代理对象。

在Activity中可以通过startService和bindService方法启动Service。一般情况下如果想获取Service的服务对象那么肯定需要通过bindService()方法,比如音乐播放器,第三方支付等。如果仅仅只是为了开启一个后台任务那么可以使用startService()方法。

3. 请描述一下Service的生命周期

service有绑定模式和非绑定模式,以及这两种模式的混合使用方式。不同的使用方法生命周期方法也不同。

  • 非绑定模式:当第一次调用startService的时候执行的方法依次为onCreate()、onStartCommand(),当Service关闭的时候调用onDestory方法。

  • 绑定模式:第一次bindService()的时候,执行的方法为onCreate()、onBind()解除绑定的时候会执行onUnbind()、onDestory()。

上面的两种生命周期是在相对单纯的模式下的情形。我们在开发的过程中还必须注意Service实例只会有一个,也就是说如果当前要启动的Service已经存在了那么就不会再次创建该Service当然也不会调用onCreate()方法。

一个Service可以被多个客户进行绑定,只有所有的绑定对象都执行了onBind()方法后该Service才会销毁,不过如果有一个客户执行了onStart()方法,那么这个时候如果所有的bind客户都执行了unBind()该Service也不会销毁。

Service的生命周期图如下所示,帮助大家记忆。

4. 什么是IntentService?有何优点?

我们通常只会使用Service,可能IntentService对大部分同学来说都是第一次听说。那么看了下面的介绍相信你就不再陌生了。如果你还是不了解那么在面试的时候你就坦诚说没用过或者不了解等。并不是所有的问题都需要回答上来的。

IntentService简介

IntentService是Service的子类,比普通的Service增加了额外的功能。先看Service本身存在两个问题:

  • service不会专门启动一条单独的进程,Service与它所在应用位于同一个进程中;

  • service也不是专门一条新线程,因此不应该在Service中直接处理耗时的任务;

IntentService特征

  • 会创建独立的worker线程来处理所有的Intent请求;

  • 会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题;

  • 所有请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service;

  • 为Service的onBind()提供默认实现,返回null;

  • 为Service的onStartCommand提供默认实现,将请求Intent添加到队列中;

使用IntentService

本人写了一个IntentService的使用例子供参考。该例子中一个MainActivity一个MyIntentService,这两个类都是四大组件当然需要在清单文件中注册。这里只给出核心代码:

MainActivity.java

public void click(View view){
    Intent intent = new Intent(this, MyIntentService.class);
    intent.putExtra("start", "MyIntentService");
    startService(intent);
}

MyIntentService.javapublic class MyIntentService extends IntentService {
    private String ex = "";

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            Toast.makeText(MyIntentService.this, "-e " + ex, Toast.LENGTH_LONG).show();
        }
    };

    public MyIntentService(){
        super("MyIntentService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ex = intent.getStringExtra("start");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
    /*
     * 模拟执行耗时任务
     * 该方法是在子线程中执行的,因此需要用到handler跟主线程进行通信
     */
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mHandler.sendEmptyMessage(0);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行后效果如下:

5. 说说Activity、Intent、Service是什么关系

他们都是Android开发中使用频率最高的类。其中Activity和Service都是Android四大组件之一。他俩都是Context类的子类ContextWrapper的子类,因此他俩可以算是兄弟关系吧。不过兄弟俩各有各自的本领,Activity负责用户界面的显示和交互,Service负责后台任务的处理。Activity和Service之间可以通过Intent传递数据,因此可以把Intent看作是通信使者。

6. Service和Activity在同一个线程吗

对于同一app来说默认情况下是在同一个线程中的,mainThread (UI Thread)。

7. Service里面可以弹吐司么

可以的。弹吐司有个条件就是得有一个Context上下文,而Service本身就是Context的子类,因此在Service里面弹吐司是完全可以的。比如我们在Service中完成下载任务后可以弹一个吐司通知用户。

results matching ""

    No results matching ""