android 進程間通訊(java)

Androd 6.0 surfaceview 繼承parceable 接口能夠跨進程傳遞,如今咱們的從最簡單的單實例開始 java

下面是客戶端進程,主要是得到服務段的IBinder ,並在客戶端調用服務端Binder 實現的方法,完成進程間的通訊。 android

@SuppressLint("NewApi")
public class MediaPlayer_Surface_iadl_TestBase extends Activity {

    private static final String LOG_TAG = MediaPlayer_Surface_iadl_TestBase.class
            .getName() + "liyl add";
    protected static final int SLEEP_TIME = 1000;
    protected static final int LONG_SLEEP_TIME = 6000;
    protected static final int STREAM_RETRIES = 1;
    protected static boolean sUseScaleToFitMode = false;

    public static class Monitor {
        private int numSignal;

        public synchronized void reset() {
            numSignal = 0;
        }

        public synchronized void signal() {
            numSignal++;
            notifyAll();
        }

        public synchronized boolean waitForSignal() throws InterruptedException {
            return waitForCountedSignals(1) > 0;
        }

        public synchronized int waitForCountedSignals(int targetCount)
                throws InterruptedException {
            while (numSignal < targetCount) {
                wait();
            }
            return numSignal;
        }

        public synchronized boolean waitForSignal(long timeoutMs)
                throws InterruptedException {
            return waitForCountedSignals(1, timeoutMs) > 0;
        }

        public synchronized int waitForCountedSignals(int targetCount,
                long timeoutMs) throws InterruptedException {
            if (timeoutMs == 0) {
                return waitForCountedSignals(targetCount);
            }
            long deadline = System.currentTimeMillis() + timeoutMs;
            while (numSignal < targetCount) {
                long delay = deadline - System.currentTimeMillis();
                if (delay <= 0) {
                    break;
                }
                wait(delay);
            }
            return numSignal;
        }

        public synchronized boolean isSignalled() {
            return numSignal >= 1;
        }

        public synchronized int getNumSignal() {
            return numSignal;
        }
    }

    /*
     * protected Monitor mOnVideoSizeChangedCalled = new Monitor(); protected
     * Monitor mOnVideoRenderingStartCalled = new Monitor(); protected Monitor
     * mOnBufferingUpdateCalled = new Monitor(); protected Monitor
     * mOnPrepareCalled = new Monitor(); protected Monitor mOnSeekCompleteCalled
     * = new Monitor(); protected Monitor mOnCompletionCalled = new Monitor();
     * protected Monitor mOnInfoCalled = new Monitor(); protected Monitor
     * mOnErrorCalled = new Monitor();
     */

    protected SurfaceHolder mSurfaceHolder1 = null;

    private SurfaceHolder mHolder1;

    protected MediaPlayer_Surface_iadl_TestBase mActivity;

     private boolean mIsRemoteBound = false;

    private IMyService mRemoteService;

    private ServiceConnection mRemoteConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            mRemoteService = IMyService.Stub.asInterface(service);
            Log.i(LOG_TAG,"mRemoteService == null is "+(mRemoteService == null));
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
            mRemoteService = null;
        }
    };

    public MediaPlayer_Surface_iadl_TestBase() {
        super();
    }

    protected void setUp() {
        mSurfaceHolder1 = getSurfaceHolder1();

         if (!mIsRemoteBound) {// 啓動service


            Intent mIntent = new Intent();
            mIntent.setAction("com.example.demo.IMyService");//你定義的service的action
            mIntent.setPackage(getPackageName());//這裏你須要設置你應用的包名
            //startService(mIntent);


            bindService(mIntent,
                    mRemoteConnection, Context.BIND_AUTO_CREATE);
            mIsRemoteBound = !mIsRemoteBound;
        }

    }

    public SurfaceHolder getSurfaceHolder1() {
        return mHolder1;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.mediaplayermultsurface);

        mActivity = this;

        SurfaceView surfaceV1 = (SurfaceView) findViewById(R.id.surface1);
        mHolder1 = surfaceV1.getHolder();

        setUp();

    }

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

    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();

        if(mRemoteService == null) {
            Log.w(LOG_TAG,"mRemoteService is null");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        mSurfaceHolder1.addCallback(new SurfaceHolder.Callback() {

            @Override
            public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
                    int arg3) {
                // TODO Auto-generated method stub
                mSurfaceHolder1 = arg0;
            }

            @Override
            public void surfaceCreated(SurfaceHolder arg0) {
                // TODO Auto-generated method stub
                try {
                  
                    mRemoteService.playLoadedVideo_iadl(mActivity.getSurfaceHolder1()
                            .getSurface());
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder arg0) {
                // TODO Auto-generated method stub
                mSurfaceHolder1 = null;
            }

        });

    }

    protected void tearDown() {
        if (!mIsRemoteBound) {
            unbindService(mRemoteConnection);
            mIsRemoteBound = !mIsRemoteBound;
        }

    }

 
    // //////////////////////////////////////////////////////////////////////

    /**
     * This is a watchdog used to stop the process if it hasn't been pinged for
     * more than specified milli-seconds. It is used like:
     *
     * Watchdog w = new Watchdog(10000); // 10 seconds. w.start(); // start the
     * watchdog. ... w.ping(); ... w.ping(); ... w.end(); // ask the watchdog to
     * stop. w.join(); // join the thread.
     */
    class Watchdog extends Thread {
        private final long mTimeoutMs;
        private boolean mWatchdogStop;
        private boolean mWatchdogPinged;

        public Watchdog(long timeoutMs) {
            mTimeoutMs = timeoutMs;
            mWatchdogStop = false;
            mWatchdogPinged = false;
        }

        public synchronized void run() {
            while (true) {
                // avoid early termination by "spurious" waitup.
                final long startTimeMs = System.currentTimeMillis();
                long remainingWaitTimeMs = mTimeoutMs;
                do {
                    try {
                        wait(remainingWaitTimeMs);
                    } catch (InterruptedException ex) {
                        // ignore.
                    }
                    remainingWaitTimeMs = mTimeoutMs
                            - (System.currentTimeMillis() - startTimeMs);
                } while (remainingWaitTimeMs > 0);

                if (mWatchdogStop) {
                    break;
                }

                if (!mWatchdogPinged) {

                    return;
                }
                mWatchdogPinged = false;
            }
        }

        public synchronized void ping() {
            mWatchdogPinged = true;
            this.notify();
        }

        public synchronized void end() {
            mWatchdogStop = true;
            this.notify();
        }
    }

} app

定義進程間通訊接口。 ide

IMySevice.aidl: this

package com.example.demo;

import android.view.Surface;

interface IMyService {
        void playLoadedVideo_iadl(in  Surface  surface);

} spa


service 以及binder 實現。 xml

MyRemoteService.java: 繼承

package com.example.demo;

import java.io.IOException;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Surface;


public class MyRemoteService extends Service {
    private static final String LOG_TAG = MyRemoteService.class.getName() + "";
    private Surface surface;
    

    @SuppressLint("NewApi")
    private final IMyService.Stub mBinder = new IMyService.Stub(){

            @Override
            public void playLoadedVideo_iadl(Surface surface)
                    throws RemoteException {
                // TODO Auto-generated method stub

                
                final Integer width = 1280;
                final Integer height = 720;
                int playTime = 0 ;
                final float leftVolume = 0.5f;
                final float rightVolume = 0.5f;
                
                
                final MediaPlayer mediaPlayer = new MediaPlayer();
                try {
                    mediaPlayer.setDataSource(Constants.getFullPath("", ""));
                } catch (IllegalArgumentException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (SecurityException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IllegalStateException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                if( surface != null) {
                    Log.i(LOG_TAG,surface.toString());
                    mediaPlayer.setSurface(surface);
                }else {
                    Log.w(LOG_TAG,"surface is NULL");
                
                }

                 //mediaPlayer.setScreenOnWhilePlaying(true);
                 
                mediaPlayer
                        .setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
                            @Override
                            public void onVideoSizeChanged(MediaPlayer mp, int w, int h) {
                                if (w == 0 && h == 0) {
                                    // A size of 0x0 can be sent initially one time when
                                    // using NuPlayer.
                                    // assertFalse(mOnVideoSizeChangedCalled.isSignalled());
                                    return;
                                }
                                // mOnVideoSizeChangedCalled.signal();
                                if (width != null) {

                                }
                                if (height != null) {

                                }
                            }
                        });
                mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {

                        return true;
                    }
                });
                mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                    @Override
                    public boolean onInfo(MediaPlayer mp, int what, int extra) {
                        if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                            // mOnVideoRenderingStartCalled.signal();
                        }
                        return true;
                    }
                });
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

                    @Override
                    public void onPrepared(MediaPlayer arg0) {
                        // TODO Auto-generated method stub

                      mediaPlayer.start();

                      mediaPlayer.setVolume(leftVolume, rightVolume);
                    }
                });

                try {
                    mediaPlayer.prepareAsync();
                } catch (Exception e) {
                    Log.w(LOG_TAG,e.toString());
                    mediaPlayer.reset();
                }



                
            
            }
    };

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return mBinder;
    }
} 接口

配置遠程服務獨立進程 進程

AndroidManifest.xml:

             <activity
            android:name="com.example.demo.MediaPlayer_Surface_iadl_TestBase"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:label="Media_Surface_StubActivity"
            android:screenOrientation="nosensor" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyRemoteService"
            android:process=":remote" >             <intent-filter>                 <action android:name="com.example.demo.IMyService" />             </intent-filter>         </service>

相關文章
相關標籤/搜索