Android学习3: SurfaceView与多线程混搭

来源:互联网 发布:云计算股票代码 编辑:程序博客网 时间:2024/04/27 00:20
今天学习了一下Android里面的多线程调用.
使用SurfaceView来显示系统文件夹下面的一些图像.
一个线程来读取图片生成Bitmap, 另个一下线程来绘制图片.
这个例子还是有一些BUG, 生成的Bitmap也可能为空. 产生程序异常.
别外就是改成可以读取任意文件夹下的图片可以绘更好一些.

算了不纠结了, 继续往后看吧.


里面还有一个回调函数.貌似有点不好理解.

sfh.addCallback(new MyCallBack());


layout/activity_main.xml

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">    <LinearLayout        android:orientation="horizontal"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:id="@+id/linearLayout">        <Button            android:layout_width="120dp"            android:layout_height="40dp"            android:text="启动多线程"            android:id="@+id/button" />    </LinearLayout>    <SurfaceView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/surfaceView"        android:layout_below="@+id/linearLayout"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        android:layout_alignParentEnd="true" /></RelativeLayout>



com/example/youtwo/testthread/MainActivity.java

package com.example.youtwo.testthread;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.Rect;import android.graphics.RectF;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.util.DisplayMetrics;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.Button;import java.lang.reflect.Field;import java.util.ArrayList;public class MainActivity extends ActionBarActivity {    Button btnDoubleThread;    SurfaceView sfv;    SurfaceHolder sfh;    int imgWidth, imgHeight;    ArrayList imgList = new ArrayList();    Bitmap bitmap;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 初始化按钮        btnDoubleThread = (Button) this.findViewById(R.id.button);        btnDoubleThread.setOnClickListener(new ClickEvent());        // 初始化绘图容器        sfv = (SurfaceView) this.findViewById(R.id.surfaceView);        sfh = sfv.getHolder();        // 自动运行surfaceCreated以及surfaceChanged        sfh.addCallback(new MyCallBack());        bitmap = null;    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }    class ClickEvent implements View.OnClickListener {        @Override        public void onClick(View v) {            if (v == btnDoubleThread) {                new LoadImage().start();//开一条线程读取                new DrawImage(imgWidth + 10, 0).start();//开一条线程绘图            }        }    };    class MyCallBack implements SurfaceHolder.Callback {        @Override        public void surfaceChanged(SurfaceHolder holder, int format, int width,                                   int height) {            Log.i("Surface:", "Change");        }        @Override        public void surfaceCreated(SurfaceHolder holder) {            Log.i("Surface:", "Create");            // 用反射机制来获取资源中的图片ID和尺寸            Field[] fields = R.drawable.class.getDeclaredFields();            for (Field field : fields) {                if (!"icon".equals(field.getName()))// 除了icon之外的图片                {                    int index = 0;                    try {                        index = field.getInt(R.drawable.class);                    } catch (IllegalArgumentException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    } catch (IllegalAccessException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    // 保存图片ID                    imgList.add(index);                }            }            // 取得图像大小            Bitmap bmImg = BitmapFactory.decodeResource(getResources(),                    (Integer) imgList.get(0));            imgWidth = bmImg.getWidth();            imgHeight = bmImg.getHeight();        }        @Override        public void surfaceDestroyed(SurfaceHolder holder) {            Log.i("Surface:", "Destroy");        }    };    /*     * 只负责绘图的线程     */    class DrawImage extends Thread {        int x, y;        public DrawImage(int x, int y) {            this.x = x;            this.y = y;        }        public void run() {            while (true) {                if (bitmap != null) {//如果图像有效                    // 获取屏幕大小                    DisplayMetrics dm = new DisplayMetrics();                    getWindowManager().getDefaultDisplay().getMetrics(dm);                    Canvas c = sfh.lockCanvas(new Rect(this.x, this.y,                            dm.widthPixels, dm.heightPixels));                    Paint mPaint = new Paint();                    // 清除屏幕                    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));                    c.drawPaint(mPaint);                    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));                    if(bitmap != null) {                        // 把系统图标缩放到当前窗口的大小显示                        Rect src = new Rect(0,0,bitmap.getWidth(), bitmap.getHeight());                        RectF dst = new RectF(0,0,dm.widthPixels,dm.heightPixels);                        c.drawBitmap(bitmap, src, dst, mPaint);                    }                    sfh.unlockCanvasAndPost(c);// 更新屏幕显示内容                }            }        }    };    /*     * 只负责读取图片的线程     */    class LoadImage extends Thread {        int imgIndex = 0;        public void run() {            while (true) {                bitmap = BitmapFactory.decodeResource(getResources(),                        (Integer) imgList.get(imgIndex));                imgIndex++;                if (imgIndex == imgList.size())//如果到尽头则重新读取                    imgIndex = 0;            }        }    };}



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米手机前置摄像头打不开怎么办 mp4视频屏幕好小怎么办 投了简历没回应怎么办 借壳上市原股票怎么办 红米note3指纹解锁失灵怎么办 来分期刷脸失败怎么办 买到假货商家不承认怎么办 买到假货翻新货工商局怎么办 三星note8笔丢了怎么办 夜跑结束后该怎么办 lol客户端正在运行中怎么办 瑞和宝终端锁定怎么办 骊爽摩托车动力弱怎么办? 换了手机跟点微信怎么办 手机送点插头换了怎么办 校园网总是显示有代理软件怎么办 电脑连接无线网络需要登录怎么办 智校园密码忘了怎么办 ivvi手机开不开机怎么办 跑鞋子大了一码怎么办 洗浴搓澡出汗多该怎么办 联华超市卡丢了怎么办 飞利浦电视的应用打不开怎么办 贵阳市下岗职工办理门面补贴怎么办 陌陌上被骗了色怎么办 七位数的座机要怎么办 开通米粉卡店铺预留电话号码怎么办 办信用卡没有单位电话怎么办 qq账号永久封停怎么办 qq号给冻结了怎么办 微信被官方封2天怎么办 天虹的卡丢了怎么办 顺丰快递到不了的地区怎么办 信用卡兑换东西超过积分怎么办 新买的冰箱坏了怎么办 买新洗衣机出现克坏怎么办 京东当日达没到达怎么办 兴隆卡不能用了怎么办 龙津时代烂尾了怎么办 三星s8电耗尽无法开机怎么办 杜鹃买回来蔫了怎么办