Android Activity与Service的通信方式

1.通过Binder对象

如果Activity通过bindService(Intent service, ServiceConnection conn, int flags)绑定Service,我们可以得到一个Service实例,然后访问Service中的方法。

代码示例如下:

MainActivity的onCreate方法绑定服务,然后在ServiceConnection的onServiceConnected回调方法中得到Service实例对象。

package com.mine.communication;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();
    private Button btn1;
    private MyService mService;

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case MyService.MSG1:
                Toast.makeText(MainActivity.this, "service send a msg !", Toast.LENGTH_LONG).show();
                break;

            default:
                break;
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindMyService();
        btn1 = (Button) findViewById(R.id.btn1);
        btn1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if(mService != null) {
                    mService.doSomething();
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        unbindService(conn);
    }

    private void bindMyService() {
        Log.d(TAG, "bindMyService");
        Intent i = new Intent(this, MyService.class);
        bindService(i, conn, Context.BIND_AUTO_CREATE);
    }

    ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected");
            mService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected");
            mService = ((MyService.ServiceBinder) service).getService();
            mService.setHandler(mHandler);
        }
    };
}

Service的代码,模拟一个任务doSomething(),事情做完后发送一个message,MainActivity的Handler将处理这个消息。

package com.mine.communication;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;

public class MyService extends Service {

    private static final String TAG = MyService.class.getSimpleName();
    public static final int MSG1 = 1;
    private Handler mHandler;
    private ServiceBinder mBinder = new ServiceBinder();

    public class ServiceBinder extends Binder {
        public MyService getService() {
            return MyService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");
        return mBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    public void doSomething() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                Log.d(TAG, "doSomething start");
                SystemClock.sleep(1000 * 5);
                sendMsg(MSG1);
                Log.d(TAG, "doSomething end");
            }
        }).start();
    }

    private void sendMsg(int code) {
        if (mHandler != null) {
            mHandler.sendEmptyMessage(code);
        }
    }

    public void setHandler(Handler handler) {
        mHandler = handler;
    }

    public Handler getHandler() {
        return mHandler;
    }

}

2. 通过广播

如果需要在Service里面执行耗时任务,不开子线程,而且执行完成后自动终止该服务,此时可以用IntentService。

IntentService不能通过bindService绑定,因为IntentService本身设计不支持bind操作,其onBind()方法被实现,而且返回null。

frameworks/base/core/java/android/app/IntentService.java
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

我们修改一下代码,用IntentService实现。Service发送广播,Activity接收广播并做相应的处理。

MainActivity.java

package com.mine.communication;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();
    private Button btn1;
    private MyReceiver receiver;

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case MyService.MSG1:
                Toast.makeText(MainActivity.this, "service send a broadcast !", Toast.LENGTH_LONG).show();
                break;

            default:
                break;
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        receiver = new MyReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(MyService.MY_ACTION);
        registerReceiver(receiver, filter);
        btn1 = (Button) findViewById(R.id.btn1);
        btn1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                startMyService();
            }
        });
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    private void startMyService() {
        Log.d(TAG, "startMyService");
        Intent i = new Intent(this, MyService.class);
        startService(i);
    }

    class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "action = " + action);
            if (action.equals(MyService.MY_ACTION)) {
                int code = intent.getIntExtra(MyService.EXTRA, -1);
                mHandler.sendEmptyMessage(code);
            }
        }
    }
}

MyService.java

扫描二维码关注公众号,回复: 9574159 查看本文章
package com.mine.communication;

import android.app.IntentService;
import android.content.Intent;
import android.os.Binder;
import android.os.SystemClock;
import android.util.Log;

public class MyService extends IntentService {

    /**
     * 必须实现空参构造方法,否则报错
     */
    public MyService() {
        super("MyService");
    }

    private static final String TAG = MyService.class.getSimpleName();
    public static final String MY_ACTION = "com.mine.communication.action";
    public static final String EXTRA = "code";
    public static final int MSG1 = 1;

    public class ServiceBinder extends Binder {
        public MyService getService() {
            return MyService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d(TAG, "onHandleIntent start");
        SystemClock.sleep(1000 * 5);
        sendBoardcast(MSG1);
        Log.d(TAG, "onHandleIntent end");

    }

    private void sendBoardcast(int code) {
        Intent i = new Intent();
        i.setAction(MY_ACTION);
        i.putExtra(EXTRA, code);
        sendBroadcast(i);
    }

}
发布了6 篇原创文章 · 获赞 2 · 访问量 355

猜你喜欢

转载自blog.csdn.net/zc37093/article/details/104037218