美文网首页
MipcaActivityCapture代码阅读-surface

MipcaActivityCapture代码阅读-surface

作者: PengPengPro | 来源:发表于2016-10-08 15:58 被阅读361次

    前言

    源代码来自http://blog.csdn.net/xiaanming/article/details/10163203,由于不懂surfaceDestroyed的调用时机,网上一般都说在surfaceview隐藏的时候调用,但是按back键、按home键、锁屏、跳转到另一个非完全覆盖的activity是否会调用surfaceDestroyed,不是很清楚。 所以用打印日志的方式分析了下各个函数的执行调用过程。
    很多surfaceview的demo中都用到了hasSurface,但是hasSurface又有什么作用呢?曾经深表怀疑,仔细分析过代码才明白
    四种方式的日志

    back

    进入MipcaActivityCapture这个activity
    01-09 16:59:51.118:E/MipcaActivityCapture(25152): onCreate
    01-09 16:59:51.141:E/MipcaActivityCapture(25152): onResume
    01-09 16:59:51.141:E/MipcaActivityCapture(25152): hasSurface=false
    01-09 16:59:51.259:E/MipcaActivityCapture(25152): surfaceCreated
    01-09 16:59:51.259:E/MipcaActivityCapture(25152): initCamera

    点back

    01-09 16:59:54.102:E/MipcaActivityCapture(25152): onPause
    01-09 16:59:54.227:E/MipcaActivityCapture(25152): surfaceDestroyed
    01-09 16:59:54.391:E/MipcaActivityCapture(25152): onStop
    01-09 16:59:54.399:E/MipcaActivityCapture(25152): onDestroy

    home

    进入MipcaActivityCapture这个activity
    01-09 16:59:51.118:E/MipcaActivityCapture(25152): onCreate
    01-09 16:59:51.141:E/MipcaActivityCapture(25152): onResume
    01-09 16:59:51.141:E/MipcaActivityCapture(25152): hasSurface=false
    01-09 16:59:51.259:E/MipcaActivityCapture(25152): surfaceCreated
    01-09 16:59:51.259:E/MipcaActivityCapture(25152): initCamera

    点home

    01-09 17:28:47.196:E/MipcaActivityCapture(26547): onPause
    01-09 17:28:47.321:E/MipcaActivityCapture(26547): surfaceDestroyed
    01-09 17:28:47.704:E/MipcaActivityCapture(26547): onStop

    锁屏

    进入MipcaActivityCapture这个activity
    01-09 17:31:03.259:E/MipcaActivityCapture(26655): onCreate
    01-09 17:31:03.282:E/MipcaActivityCapture(26655): hasSurface=false
    01-09 17:31:03.282:E/MipcaActivityCapture(26655): onResume
    01-09 17:31:03.438:E/MipcaActivityCapture(26655): surfaceCreated
    01-09 17:31:03.438:E/MipcaActivityCapture(26655): initCamera

    锁屏(按关机键)

    01-09 17:31:09.907:E/MipcaActivityCapture(26655): onPause
    01-09 17:31:09.938:E/MipcaActivityCapture(26655): onStop

    解锁(按关机键)

    01-09 17:35:51.509:E/MipcaActivityCapture(27383): onResume
    01-09 17:35:51.509:E/MipcaActivityCapture(27383): hasSurface=true
    01-09 17:35:51.509:E/MipcaActivityCapture(27383): initCamera

    跳转到一个非完全覆盖的activity

    进入MipcaActivityCapture这个activity
    01-09 17:43:38.126:E/MipcaActivityCapture(27383): onCreate
    01-09 17:43:38.165:E/MipcaActivityCapture(27383): onResume
    01-09 17:43:38.165:E/MipcaActivityCapture(27383): hasSurface=false
    01-09 17:43:38.251:E/MipcaActivityCapture(27383): surfaceCreated
    01-09 17:43:38.251:E/MipcaActivityCapture(27383): initCamera

    跳转到一个非完全覆盖的activity时

    01-09 17:43:44.446:E/MipcaActivityCapture(27383): onPause
    01-09 17:43:44.477: E/OtherActivity(27383):---------------onCreate--------------------
    01-09 17:43:44.477: E/OtherActivity(27383):---------------onStart--------------------
    01-09 17:43:44.477: E/OtherActivity(27383):---------------onResume--------------------

    按back

    01-09 17:43:50.954: E/OtherActivity(27383):---------------onPause--------------------
    01-09 17:43:50.977:E/MipcaActivityCapture(27383): onResume
    01-09 17:43:50.977: E/MipcaActivityCapture(27383):hasSurface=true
    01-09 17:43:50.977:E/MipcaActivityCapture(27383): initCamera
    01-09 17:43:51.954: E/OtherActivity(27383):---------------onStop--------------------
    01-09 17:43:51.954: E/OtherActivity(27383):---------------onDestroy--------------------

    总结

    onPause会调用CameraManager.get().closeDriver();
    surfaceCreated一般在OnResume之后调用,
    按back或home都会调用surfaceDestroyed ,surfaceDestroyed在OnPause和OnStop之间调用。
    但是锁屏不会调用surfaceDestroyed,解锁也不会调surfaceCreated
    跳转到一个非完全覆盖的activity时也不会调surfaceDestroyed,返回时也不会调surfaceCreated

    按back/home或者锁屏都会调用OnPause,导致CameraManager.get().closeDriver();所以下次进入activity的时候要initCamera,这是怎么实现的呢?看下面这段代码,展现了hasSurface的作用。

            if(hasSurface) {
                initCamera(surfaceHolder);
            }else {
                surfaceHolder.addCallback(this);
                surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
    

    锁屏解锁后hasSurface为true,调用initCamera。
    按back或者home再回来时hasSurface为false,此时在onResume之后会调用surfaceCreated,在surfaceCreated里面会调用initCamera。
    代码
    稍微改了下原代码

    view plain copy

    在CODE上查看代码片在CODE上查看代码片 派生到我的代码片派生到我的代码片
    package com.example.qr_codescan;  
      
    import java.io.IOException;  
    import java.util.Vector;  
      
    import android.app.Activity;  
    import android.app.AlertDialog;  
    import android.app.Dialog;  
    import android.content.Intent;  
    import android.content.res.AssetFileDescriptor;  
    import android.graphics.Bitmap;  
    import android.media.AudioManager;  
    import android.media.MediaPlayer;  
    import android.media.MediaPlayer.OnCompletionListener;  
    import android.os.Bundle;  
    import android.os.Handler;  
    import android.os.Vibrator;  
    import android.util.Log;  
    import android.view.SurfaceHolder;  
    import android.view.SurfaceHolder.Callback;  
    import android.view.SurfaceView;  
    import android.view.View;  
    import android.view.View.OnClickListener;  
    import android.widget.Button;  
    import android.widget.Toast;  
      
    import com.google.zxing.BarcodeFormat;  
    import com.google.zxing.Result;  
    import com.mining.app.zxing.camera.CameraManager;  
    import com.mining.app.zxing.decoding.CaptureActivityHandler;  
    import com.mining.app.zxing.decoding.InactivityTimer;  
    import com.mining.app.zxing.view.ViewfinderView;  
    /** 
     * Initial the camera 
     * @author Ryan.Tang 
     */  
    public class MipcaActivityCapture extends Activity implements Callback {  
      
        private static final String TAG = MipcaActivityCapture.class.getSimpleName();  
        private CaptureActivityHandler handler;  
        private ViewfinderView viewfinderView;  
        private boolean hasSurface;  
        private Vector<BarcodeFormat> decodeFormats;  
        private String characterSet;  
        private InactivityTimer inactivityTimer;  
        private MediaPlayer mediaPlayer;  
        private boolean playBeep;  
        private static final float BEEP_VOLUME = 0.10f;  
        private boolean vibrate;  
        Button btn;  
      
        /** Called when the activity is first created. */  
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            Log.e(TAG, "onCreate");  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_capture1);  
            //ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card);  
            CameraManager.init(getApplication());  
            viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);  
              
            Button mButtonBack = (Button) findViewById(R.id.button_back);  
            mButtonBack.setOnClickListener(new OnClickListener() {  
                  
                @Override  
                public void onClick(View v) {  
                    MipcaActivityCapture.this.finish();  
                      
                }  
            });  
            hasSurface = false;  
            inactivityTimer = new InactivityTimer(this);  
              
            btn=(Button) findViewById(R.id.btn1);  
            btn.setOnClickListener(new OnClickListener() {  
                  
                @Override  
                public void onClick(View v) {  
      
                    Intent intent=new Intent(MipcaActivityCapture.this, OtherActivity.class);  
                    startActivity(intent);  
                      
                }  
            });  
        }  
      
        @Override  
        protected void onResume() {  
            Log.e(TAG, "onResume");  
            super.onResume();  
            SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);  
            SurfaceHolder surfaceHolder = surfaceView.getHolder();  
            Log.e(TAG, "hasSurface="+hasSurface);  
            if (hasSurface) {  
                initCamera(surfaceHolder);  
            } else {  
                surfaceHolder.addCallback(this);  
                surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
            }  
            decodeFormats = null;  
            characterSet = null;  
      
            playBeep = true;  
            AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);  
            if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {  
                playBeep = false;  
            }  
            initBeepSound();  
            vibrate = true;  
       
              
        }  
      
        @Override  
        protected void onPause() {  
            super.onPause();  
            if (handler != null) {  
                handler.quitSynchronously();  
                handler = null;  
            }  
            CameraManager.get().closeDriver();  
      
            Log.e(TAG, "onPause");  
        }  
      
        @Override  
        protected void onStop() {  
            // TODO Auto-generated method stub  
            super.onStop();  
            Log.e(TAG, "onStop");  
        }  
        @Override  
        protected void onDestroy() {  
            inactivityTimer.shutdown();  
            super.onDestroy();  
            Log.e(TAG, "onDestroy");  
        }  
          
        /** 
         * 处理扫描结果 
         * @param result 
         * @param barcode 
         */  
        public void handleDecode(Result result, Bitmap barcode) {  
            inactivityTimer.onActivity();  
            playBeepSoundAndVibrate();  
            String resultString = result.getText();  
            if (resultString.equals("")) {  
                Toast.makeText(MipcaActivityCapture.this, "Scan failed!", Toast.LENGTH_SHORT).show();  
            }else {  
                Intent resultIntent = new Intent();  
                Bundle bundle = new Bundle();  
                bundle.putString("result", resultString);  
                bundle.putParcelable("bitmap", barcode);  
                resultIntent.putExtras(bundle);  
                this.setResult(RESULT_OK, resultIntent);  
            }  
            MipcaActivityCapture.this.finish();  
        }  
          
        private void initCamera(SurfaceHolder surfaceHolder) {  
      
            Log.e(TAG, "initCamera");  
            try {  
                CameraManager.get().openDriver(surfaceHolder);  
            } catch (IOException ioe) {  
                return;  
            } catch (RuntimeException e) {  
                return;  
            }  
            if (handler == null) {  
                handler = new CaptureActivityHandler(this, decodeFormats,  
                        characterSet);  
            }  
        }  
      
        @Override  
        public void surfaceChanged(SurfaceHolder holder, int format, int width,  
                int height) {  
      
        }  
      
        @Override  
        public void surfaceCreated(SurfaceHolder holder) {  
      
            Log.e(TAG, "surfaceCreated");  
            if (!hasSurface) {  
                hasSurface = true;  
                initCamera(holder);  
            }  
      
        }  
      
        @Override  
        public void surfaceDestroyed(SurfaceHolder holder) {  
            hasSurface = false;  
      
            Log.e(TAG, "surfaceDestroyed");  
      
        }  
      
        public ViewfinderView getViewfinderView() {  
            return viewfinderView;  
        }  
      
        public Handler getHandler() {  
            return handler;  
        }  
      
        public void drawViewfinder() {  
            viewfinderView.drawViewfinder();  
      
        }  
      
        private void initBeepSound() {  
            if (playBeep && mediaPlayer == null) {  
                // The volume on STREAM_SYSTEM is not adjustable, and users found it  
                // too loud,  
                // so we now play on the music stream.  
                setVolumeControlStream(AudioManager.STREAM_MUSIC);  
                mediaPlayer = new MediaPlayer();  
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  
                mediaPlayer.setOnCompletionListener(beepListener);  
      
                AssetFileDescriptor file = getResources().openRawResourceFd(  
                        R.raw.beep);  
                try {  
                    mediaPlayer.setDataSource(file.getFileDescriptor(),  
                            file.getStartOffset(), file.getLength());  
                    file.close();  
                    mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);  
                    mediaPlayer.prepare();  
                } catch (IOException e) {  
                    mediaPlayer = null;  
                }  
            }  
        }  
      
        private static final long VIBRATE_DURATION = 200L;  
      
        private void playBeepSoundAndVibrate() {  
            if (playBeep && mediaPlayer != null) {  
                mediaPlayer.start();  
            }  
            if (vibrate) {  
                Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);  
                vibrator.vibrate(VIBRATE_DURATION);  
            }  
        }  
      
        /** 
         * When the beep has finished playing, rewind to queue up another one. 
         */  
        private final OnCompletionListener beepListener = new OnCompletionListener() {  
            public void onCompletion(MediaPlayer mediaPlayer) {  
                mediaPlayer.seekTo(0);  
            }  
        };  
    }  
    

    相关文章

      网友评论

          本文标题:MipcaActivityCapture代码阅读-surface

          本文链接:https://www.haomeiwen.com/subject/hiftsttx.html