深入Android架构(从线程到AIDL)_06 短程通信 vs. 远程通信

目录

7、 短程通信 vs. 远程通信

範例: 短程通信

撰写步骤

範例: 遠程通信


7、 短程通信 vs. 远程通信

範例: 短程通信
  • 首先出现ac01画面,立即启动myService,定时连续传来数字,如下:
  • 由于定时连续传来数字,所以数字会持续递增,如下 :
// AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.misoo.pkm"
android:versionCode="1"
android:versionName="1.0.0">
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<activity android:name=".ac01“
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".myService" > </service>
</application>
</manifest>
  • 这AndroidManifest.xml指定了: ac01和myService是在同一进程里执行。
撰写步骤

Step-1: 定义 IListener接口:
 

// IListener.java
package com.misoo.ppvv;
public interface IListener {
    public void update(String s);
}

// ac01.java
// …….
public class ac01 extends Activity implements OnClickListener {
    private final int WC =
        LinearLayout.LayoutParams.WRAP_CONTENT;
    private TextView tx;
    private Button btn;

    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        LinearLayout.LayoutParams param =
            new LinearLayout.LayoutParams(100, WC);
        param.topMargin = 5;
        tx = new TextView(this); tx.setTextSize(26);
        tx.setTextColor(Color.RED);
        tx.setBackgroundResource(R.drawable.x_yellow);
        layout.addView(tx, param);
        btn = new Button(this); btn.setText("Exit");
        btn.setBackgroundResource(R.drawable.earth);
        btn.setOnClickListener(this);
        layout.addView(btn, param);
        this.setContentView(layout);
        //------------------------------------------------------------------
        myService.setUpdateListener( new UpdateUIListener() );
        Intent svc = new Intent(this, myService.class);
        startService(svc);
    }

    @Override protected void onDestroy() {
        super.onDestroy();
        Intent svc = new Intent(this, myService.class);
        stopService(svc);
    }

    class UpdateUIListener implements IListener {
        public void update(String s) tx.setText(" " + s);
    }

    public void onClick(View v) { this.finish(); }
}
  • 诞生一个UpdateUIListner的对象,然后将此对象之参考值(Reference)传递给myService,存于plis参考变量里。

       

// myService.java
// ……..
public class myService extends Service {
    private static IListener plis;
    private static int k = 0;
    private Timer timer = new Timer();
    public Handler handler = new Handler(){
        public void handleMessage(Message msg) {
            plis.update(String.valueOf(k++));
        }
    };

    @Override public void onCreate() {
        super.onCreate();
        TimerTask task = new TimerTask() {

            @Override public void run() {
                handler.sendEmptyMessage(0);
            }};

            timer.schedule(task,1000, 4000);
        }

    @Override public IBinder onBind(Intent intent)
        { return null; }

    public static void setUpdateListener(IListener listener)
        { plis = listener; }
}

  • 接着,诞生一个Intent对象去要求Android启动myService。就执行到myService的onCreate()函数。
  • 此onCreate()函数诞生一个Timer对象,它会定时呼叫Handler类别的handleMessage()函数。
  • 此onCreate()函数就透过plis而将数据传递给ac01里的UpdateUIListner对象,然后将数字呈现于画面上,并且循环下去。

          

// AndroidManifest.xml

//……..
<service android:name=".myService" android:process=":remote" >
<intent-filter>
<action android:name
="com.misoo.pkm.REMOTE_SERVICE" />
</intent-filter></service>
</manifest>

範例: 遠程通信
  • 兹拿刚才的MP3播放范例,来说明其详细步骤。 Activity类想跨进程去调用MediaPlayer播放引擎,如下图所示:

      

// myActivity.java
// ……..
public class myActivity extends Activity implements OnClickListener
{
    private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
    private final int FP = LinearLayout.LayoutParams.FILL_PARENT;
    private Button btn, btn2, btn3;
    public TextView tv;
    private IBinder ib = null;
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        btn = new Button(this); btn.setId(101); btn.setText("play");
        btn.setBackgroundResource(R.drawable.heart);
        btn.setOnClickListener(this);

        LinearLayout.LayoutParams param = new
        LinearLayout.LayoutParams(80, 50);
        param.topMargin = 10;
        layout.addView(btn, param);
        btn2 = new Button(this); btn2.setId(102); btn2.setText("stop");
        btn2.setBackgroundResource(R.drawable.heart);
        btn2.setOnClickListener(this);
        layout.addView(btn2, param);
        btn3 = new Button(this); btn3.setId(103); btn3.setText("exit");
        btn3.setBackgroundResource(R.drawable.heart);
        btn3.setOnClickListener(this);
        layout.addView(btn3, param);
        tv = new TextView(this); tv.setTextColor(Color.WHITE);
        tv.setText("Ready");
        LinearLayout.LayoutParams param2 = new LinearLayout.LayoutParams(FP, WC);
        param2.topMargin = 10;

        layout.addView(tv, param2);
        setContentView(layout);
        //-------------------------------------------------------------------------------
        // startService(…)
        bindService(new Intent("com.misoo.kx02c.REMOTE_SERVICE"),
        mConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName,className, IBinder ibinder) {
        ib = ibinder;
    }

    public void onServiceDisconnected(ComponentName,className) {}
};

public void onClick(View v) {
    switch (v.getId()) {
    case 101:
        Parcel pc = Parcel.obtain();
        Parcel pc_reply = Parcel.obtain();
        pc.writeString("playing");
        try {
            ib.transact(1, pc, pc_reply, 0);
            tv.setText(pc_reply.readString());
        } catch (Exception e) { e.printStackTrace(); } break;
    case 102:
        pc = Parcel.obtain(); pc_reply = Parcel.obtain();
        pc.writeString("stop");
        try { ib.transact(2, pc, pc_reply, 0);
            tv.setText(pc_reply.readString());
        } catch (Exception e) { e.printStackTrace(); }
        break;
    case 103: finish(); break;
}}}
  • App启动时(就会把App的 load到内存里,此刻通称为loading-time。在这个时刻,就会创建了mConnection对象。
  • 因为mConnection对象不是属于特定函数内的对象,而是属于类的对象,各函数都可用的公用对象。这种static对象(或变量)都是loading-time就创建了。
  • App被load进来之后,才会启动(创建)myActivity对象,之后才会调用myActivity的onCreate()函数。
// myService.java
// …….
public class myService extends Service {
    private IBinder mBinder = null;
    @Override public void onCreate() {
        mBinder = new myBinder(getApplicationContext());
    }

    @Override public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

// myBinder.java
// ……..
public class myBinder extends Binder{
    private MediaPlayer mPlayer = null;
    private Context ctx;
    public myBinder(Context cx)
        { ctx= cx; }

    @Override public boolean onTransact(int code,Parcel data, Parcel reply, int flags)
        throws android.os.RemoteException
    {
        reply.writeString(data.readString()+ " mp3");
        if(code == 1)
            this.play();
        else if(code == 2)
            this.stop();
        return true;
    }

    public void play(){
        if(mPlayer != null) return;
        mPlayer = MediaPlayer.create(ctx, R.raw.test_cbr);
        try { mPlayer.start();
        }catch (Exception e)
        { Log.e("StartPlay", "error: " + e.getMessage(), e);}
    }

    public void stop(){
        if (mPlayer != null) {
            mPlayer.stop(); mPlayer.release(); mPlayer = null; 
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思忖小下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值