Android Server的bind()与unbind(),以及解绑异常

面试的时候被问到这样一个问题,绑定server之后如果不解绑,程序会Crash吗?我擦,蒙逼了,回去之后试了试,不会异常,但是会泄漏

1.异常一:先看一下报的异常吧

12-09 21:03:31.596 5771-5771/com.oblivion.changeactivity I/System.out: oncreate
12-09 21:03:31.596 5771-5771/com.oblivion.changeactivity I/System.out: onbind
12-09 21:03:34.816 5771-5771/com.oblivion.changeactivity E/ActivityThread: Activity com.oblivion.changeactivity.utils.MainActivity has leaked ServiceConnection com.oblivion.changeactivity.utils.MainActivity$MyConn@5281f840 that was originally bound here
                                                                           android.app.ServiceConnectionLeaked: Activity com.oblivion.changeactivity.utils.MainActivity has leaked ServiceConnection com.oblivion.changeactivity.utils.MainActivity$MyConn@5281f840 that was originally bound here
                                                                               at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:970)
                                                                               at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:864)
                                                                               at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1577)
                                                                               at android.app.ContextImpl.bindService(ContextImpl.java:1560)
                                                                               at android.content.ContextWrapper.bindService(ContextWrapper.java:517)
                                                                               at com.oblivion.changeactivity.utils.MainActivity.bind(MainActivity.java:26)
                                                                               at java.lang.reflect.Method.invokeNative(Native Method)
                                                                               at java.lang.reflect.Method.invoke(Method.java:515)
                                                                               at android.view.View$1.onClick(View.java:3818)
                                                                               at android.view.View.performClick(View.java:4438)
                                                                               at android.view.View$PerformClick.run(View.java:18422)
                                                                               at android.os.Handler.handleCallback(Handler.java:733)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                               at android.os.Looper.loop(Looper.java:136)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5001)
                                                                               at java.lang.reflect.Method.invokeNative(Native Method)
                                                                               at java.lang.reflect.Method.invoke(Method.java:515)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                                                                               at dalvik.system.NativeStart.main(Native Method)
12-09 21:03:34.816 5771-5771/com.oblivion.changeactivity I/System.out: onunbind
12-09 21:03:34.816 5771-5771/com.oblivion.changeactivity I/System.out: onDestroy

这种异常是直接bind之后退出程序(界面不可见出现问题,如果直接干掉程序是没问题的)

2.异常二,不绑定直接退出,也会出异常
同样看一叙异常

12-09 21:12:22.766 20054-20054/com.oblivion.changeactivity D/AndroidRuntime: Shutting down VM
12-09 21:12:22.766 20054-20054/com.oblivion.changeactivity W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa4d27b20)
12-09 21:12:22.766 20054-20054/com.oblivion.changeactivity E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.oblivion.changeactivity, PID: 20054
                                                                             java.lang.IllegalStateException: Could not execute method of the activity
                                                                                 at android.view.View$1.onClick(View.java:3823)
                                                                                 at android.view.View.performClick(View.java:4438)
                                                                                 at android.view.View$PerformClick.run(View.java:18422)
                                                                                 at android.os.Handler.handleCallback(Handler.java:733)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:136)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5001)
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                                                                                 at dalvik.system.NativeStart.main(Native Method)
                                                                              Caused by: java.lang.reflect.InvocationTargetException
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                 at android.view.View$1.onClick(View.java:3818)
                                                                                 at android.view.View.performClick(View.java:4438) 
                                                                                 at android.view.View$PerformClick.run(View.java:18422) 
                                                                                 at android.os.Handler.handleCallback(Handler.java:733) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                 at android.os.Looper.loop(Looper.java:136) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5001) 
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
                                                                                 at dalvik.system.NativeStart.main(Native Method) 
                                                                              Caused by: java.lang.IllegalArgumentException: connection is null
                                                                                 at android.app.ContextImpl.unbindService(ContextImpl.java:1608)
                                                                                 at android.content.ContextWrapper.unbindService(ContextWrapper.java:529)
                                                                                 at com.oblivion.changeactivity.utils.MainActivity.unbind(MainActivity.java:53)
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                                 at android.view.View$1.onClick(View.java:3818) 
                                                                                 at android.view.View.performClick(View.java:4438) 
                                                                                 at android.view.View$PerformClick.run(View.java:18422) 
                                                                                 at android.os.Handler.handleCallback(Handler.java:733) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                 at android.os.Looper.loop(Looper.java:136) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5001) 
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
                                                                                 at dalvik.system.NativeStart.main(Native Method) 

光说不练不怎么会体会到,我放一下完整代码,大家跑一下看看


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".utils.MainActivity" >

    <Button
        android:onClick="bind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="绑定服务" />

    <Button
        android:onClick="call"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="调用服务的方法" />

    <Button
        android:onClick="unbind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="解除绑定服务" />

LinearLayout>

MainActivity

package com.oblivion.changeactivity.utils;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;

import com.oblivion.changeactivity.R;

public class MainActivity extends Activity {
    IService iService;
    MyConn conn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void bind(View view) {
        Intent intent = new Intent(this, TestService.class);
        conn = new MyConn();
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    private class MyConn implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iService = (IService) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }

    }

    /**
     * 调用借口方法
     *
     * @param view
     */
    public void call(View view) {
        iService.callMethodInService();
    }

    public void unbind(View view) {
        unbindService(conn);
        conn = null;
    }

}

Server

package com.oblivion.changeactivity.utils;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;

public class TestService extends Service {

    private class MyBinder extends Binder implements IService {
        @Override
        public void callMethodInService() {
            methodInService();
        }
    }

    private void methodInService() {
        Toast.makeText(this, "调用Bind方法", Toast.LENGTH_SHORT).show();
    }

    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("onbind");
        return new MyBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("onunbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        System.out.println("onstart");
        super.onStart(intent, startId);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onCreate() {
        System.out.println("oncreate");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        System.out.println("onDestroy");
        super.onDestroy();
    }


}

Iserver接口

package com.oblivion.changeactivity.utils;

public interface IService {
    /**
     * 服务方法
     */
    public void callMethodInService();
}

不要忘记在清单中配置

 <service android:name=".utils.TestService">service>

你可能感兴趣的:(异常处理)