android之多线程编程

好郁闷,写了好长时间,不小心按到舍弃。。。。。。。

android中的多线程编程可以说是式采用了java当中的模式,但是java所提供的技术有时候满足不了android的需求。在android当中,有些操作需要在子线程当中完成,比如网络编程,而有些操作需要在主线程挡住完成,比如UI更新。那么问题来了,我们要怎么把网络上获取的数据传送到子线程当中来进行UI更新呢。什么?static?别闹了,会死人的。那么这里android给我么提供了一种消息的传送机制,来满足我们这些需求。简单的说,android给我们提供了一个消息队列,让我们可以在子线程当中把网络上获取的数据送到消息队列当中去,而这个消息队列的目的地,可以是主线程当中,所以我们可以在主线程当中来接受这些数据,来进行只能在主线程当中完成的数据操作。

第一种方式,Thread+Handler:

public class MainActivity extends AppCompatActivity {

    Button button1, button2;
    TextView textView1;
    ImageView imageView1;
    //这里我喜欢static,可以再其他类中用类名调用
    static MyHandler myHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView1 = (TextView) findViewById(R.id.textview1);
        imageView1 = (ImageView) findViewById(R.id.imageview1);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);

        //这步别忘了,必须放在主线程当中,最好放在setContentView后面
        myHandler = new MyHandler();

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new MyRunnable()).start();
            }
        });


    }

    //在子线程当中执行的任务
    class MyRunnable implements Runnable {
        @Override
        public void run() {
            //个人喜欢这种方式创建Message对象,不绑定handler,比较灵活
            Message message = Message.obtain();
            //分别加载数据
            message.arg1 = 1;
            message.arg2 = 2;
            message.obj = "obj";
            message.what = 3;
            message.setData(new Bundle());
            //这能体现灵活,可以使用不同的多个handler来发送同一个message
            myHandler.sendMessage(message);
        }
    }

    //在主线程当中执行的任务
    class MyHandler extends Handler {
        //在activity当中都有默认的looper对象来绑定handler
        public MyHandler() {
            super();
        }

        //在有的类当中,我们需要自己创建一个Looper looper = Looper.myLooper();
        public MyHandler(Looper looper) {
            super(looper);
        }

        //在主线程当中处理的事务
        @Override
        public void handleMessage(Message msg) {
            //这里可以把所有的数据都取出来,然后进行数据操作,这里只取了一个
            textView1.setText(msg.obj.toString());
        }
    }
}

第二种方式,AsyncTask异步任务,其实这个方法的内部实现也是Thread+Handler,只不过是把他们封装起来了。这点就像是IntentServer和Server的区别。当面向对象嘛,优点之一就是能消除很多重复的代码,方便实用嘛。

这里写了一个下载网络图片的代码功能:

public class MainActivity extends AppCompat的Activity {

    Button button1, button2;
    TextView textView1;
    ImageView imageView1;
    static String PATH = "http://e.hiphotos.baidu.com/image/pic/item/dcc451da81cb39db026e7657d2160924ab183000.jpg";
    ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView1 = (TextView) findViewById(R.id.textview1);
        imageView1 = (ImageView) findViewById(R.id.imageview1);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //注意这里的执行方法,只有一个参数
                new MyTask().execute(PATH);
            }
        });


    }

    /**
     * 声明一个类继承AsyncTask并标注三个参数
     * 1.第一个参数表示要执行的任务通常是网络的途径
     * 2.第二个参数表示进度的刻度
     * 3.第三个参数表示任务执行的返回结果
     */
    class MyTask extends AsyncTask<String, Integer, Bitmap> {
        //在mainThread当中,表示任务执行之前的操作
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setTitle("提示信息");
            progressDialog.setMessage("正在下载中...");
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.show();
        }

        //在子线程当中,主要完成耗时操作
        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bitmap = null;
            InputStream inputStream = null;
            //这里就不用null了
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            try {
                URL url = new URL(PATH);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setDoInput(true);
                httpURLConnection.setConnectTimeout(3000);
                int responseCode = httpURLConnection.getResponseCode();
                if (responseCode == 200)
                    inputStream = httpURLConnection.getInputStream();
                if (inputStream != null) {
                    byte[] bytes = new byte[1024];
                    int len = -1;
                    //先获取文件的总长度
                    long file_len = httpURLConnection.getContentLength();
                    //当前已下载长度
                    int current_len = 0;
                    while ((len = inputStream.read(bytes)) != -1) {
                        current_len += len;
                        int value = (int) ((current_len / (float) file_len) * 100);
                        //把刻度发布到onProgressUpdate方法当中
                        publishProgress(value);
                        //将读入的数据再次写入到字节流当中,这里的第三个参数不能是bytes.length
                        byteArrayOutputStream.write(bytes, 0, len);
                    }
                }
                byte[] result = byteArrayOutputStream.toByteArray();
                bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (inputStream != null)
                        inputStream.close();
                    byteArrayOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return bitmap;
        }

        //在mainThread当中,主要用于更新Bar的progress
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            progressDialog.setProgress(values[0]);
        }

        //在mainThread当中,主要更新UI操作
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            progressDialog.dismiss();
            imageView1.setImageBitmap(bitmap);
        }
    }

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值