Android低阶之【chapter - 6】Handler结合网络访问的使用方法,通过Handler实现异步网络请求

Android低阶之【chapter - 6】Handler结合网络访问的使用方法,通过Handler实现异步网络请求


本章讲到如何使用Handler结合网络请求实现,异步加载图片。

大致思路

主线程也称作UI线程,只准主线程更新UI,子线程不能更新UI,在android中耗时任务大于5秒,都会报ANR(Application Not Response)错误。解决ANR错误的方法是,将耗时任务(网络任务请求,数据库操作请求)由主线程交给子线程来运行.

  • 声明一个Handler对象
  • 重写handleMessage方法
  • 创建一个声明Handler类对象
  • 子线程创建一个Message对象,使用其属性发送信息
  • 用sendmessage发送
  • 在重写的HandleMessage中接受发送的消息

以下的code是从网上下载图片,并显示在app中,用到了Handler(子线程到主线程)

package com.example.yangjie.picture;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;//有两个Handler包,别导错了
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends AppCompatActivity {
    private ImageView mimageView ;
    private BitmapHandler  mHandler ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super .onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mimageView =(ImageView)findViewById(R.id.activity_iv_image);
        mHandler =new BitmapHandler();

        new Thread(){
            @Override
            public void run() {
              Bitmap bitmap=  dowload("http://10.7.154.201:8080/teach/tools/adc.jpg" );
                //http://10.7.154.201:8080/teach/tools/adc.jpg            //连接老师的服务器url
               // http://pic1.nipic.com/2008-09-08/200898163242920_2.jpg  //连接网络地址url

                Message msg= new Message();
                msg.obj=bitmap;
                mHandler.sendMessage(msg);
            }
        }.start();
    }
    private  class BitmapHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            Bitmap bitmap=(Bitmap)msg.obj;
            mimageView.setImageBitmap(bitmap);

        }
    }

private Bitmap dowload(String urlstr){

    try {
        URL url=new URL(urlstr);
        HttpURLConnection coon=(HttpURLConnection)url.openConnection();
        if (coon.getResponseCode()==200 ){
            InputStream is=coon.getInputStream();
            ByteArrayOutputStream bao=new ByteArrayOutputStream();
            int len=0 ;
            byte[] buf=new byte[1024 ];
            while((len=is.read(buf))!=-1){
                bao.write(buf,0,len);
            }

            Bitmap bitmap=BitmapFactory.decodeByteArray(bao.toByteArray(), 0,bao.size());
            return  bitmap;

        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return  null ;
}
}

这里写图片描述

Handler:负责消息的接受,然后处理消息
Message:消息的载体
MessageQueue:消息队列,消息共享,存放消息的数据
Looper:当前线程维护消息队列,循环遍历

以下的code是从(子线程到主线程)和从(主线程到子线程)

package com.example.yangjie.anrapp;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {
    private  final  static  String LOG_TAG="MainActivity";
    private EditText mnumber1 ,mnumber2 ;
    private Button btadd ,sendto ,startto ;
    private TextView mresult ;

    private  MessageHandler mhandler;
    private  Handler  msenhandler;

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

        mnumber1 =(EditText)findViewById(R.id.number1);
        mnumber2 =(EditText)findViewById(R.id.number2);
        btadd =(Button)findViewById(R.id.add);
        sendto =(Button)findViewById(R.id.sendto);
        startto =(Button)findViewById(R.id.startto);
        mresult =(TextView)findViewById(R.id.result);

        mhandler =new MessageHandler();




        btadd .setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final int first = Integer. parseInt(mnumber1.getText().toString());
                final int second = Integer. parseInt(mnumber2.getText().toString());
                new Thread() {
                    @Override
                    public void run() {
                        int result = add( first, second);
                        Message msg = new Message();
                        msg. what = result;
                        mhandler.sendMessage(msg);
                    }
                }.start();
            }
        });

***************************************************************************************************************


        sendto .setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                Message msg=new Message();
                msg.obj="发送了消息到子线程" ;
                msenhandler.sendMessage(msg);

            }
        });

***************************************************************************************************************

        startto .setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(){
                    @Override
                    public void run() {
                        Log. v(LOG_TAG,"YJ----->"+ "线程已启动" );
                        Looper. prepare();
                        msenhandler= new Handler(){
                            @Override
                            public void handleMessage(Message msg) {
                                Log. v(LOG_TAG,"YJ----->"+msg. obj);
                            }
                        };
                        Looper. loop();
                                                                //子线程用handleMessage接受消息,一定要用 Looper. prepare();     Looper. loop(); 
                    }

                }.start();

            }
        });

    }

    private  class  MessageHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {

            int finalresult=msg.what;
            mresult.setText(finalresult + "");

        }
    }

    public  int  add(int a,int b){
        return  (a+b);
    }

}

这里写图片描述


重要公告
博主的github,有一些有意思的小东西,欢迎来打扰。(https://github.com/KellenHu

package com.zhy.http.okhttp; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; import android.util.Log; import com.zhy.http.okhttp.cookie.SimpleCookieJar; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Response; import com.zhy.http.okhttp.builder.GetBuilder; import com.zhy.http.okhttp.builder.PostFileBuilder; import com.zhy.http.okhttp.builder.PostFormBuilder; import com.zhy.http.okhttp.builder.PostStringBuilder; import com.zhy.http.okhttp.callback.Callback; import com.zhy.http.okhttp.https.HttpsUtils; import com.zhy.http.okhttp.request.RequestCall; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; /** * Created by zhy on 15/8/17. */ public class OkHttpUtils { public static final String TAG = "OkHttpUtils"; public static final long DEFAULT_MILLISECONDS = 10000; private static OkHttpUtils mInstance; private OkHttpClient mOkHttpClient; private Handler mDelivery; private OkHttpUtils() { OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); //cookie enabled okHttpClientBuilder.cookieJar(new SimpleCookieJar()); mDelivery = new Handler(Looper.getMainLooper()); if (true) { okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); } mOkHttpClient = okHttpClientBuilder.build(); } private boolean debug; private String tag; public OkHttpUtils debug(String tag) { debug = true; this.tag = tag; return this; } public static OkHttpUtils getInstance() { if (mInstance == null) { synchronized (OkHttpUtils.class) { if (mInstance == null) { mInstance = new OkHttpUtils(); } } } return mInstance; } public Handler getDelivery() { return mDelivery; } public OkHttpClient getOkHttpClient() { return mOkHttpClient; } public static GetBuilder get() { return new GetBuilder(); } public static PostStringBuilder postString() { return new PostStringBuilder(); } public static PostFileBuilder postFile() { return new PostFileBuilder(); } public static PostFormBuilder post() { return new PostFormBuilder(); } public void execute(final RequestCall requestCall, Callback callback) { if (debug) { if(TextUtils.isEmpty(tag)) { tag = TAG; } Log.d(tag, "{method:" + requestCall.getRequest().method() + ", detail:" + requestCall.getOkHttpRequest().toString() + "}"); } if (callback == null) callback = Callback.CALLBACK_DEFAULT; final Callback finalCallback = callback; requestCall.getCall().enqueue(new okhttp3.Callback() { @Override public void onFailure(Call call, final IOException e) { sendFailResultCallback(call, e, finalCallback); } @Override public void onResponse(final Call call, final Response response) { if (response.code() >= 400 && response.code() <= 599) { try { sendFailResultCallback(call, new RuntimeException(response.body().string()), finalCallback); } catch (IOException e) { e.printStackTrace(); } return; } try { Object o = finalCallback.parseNetworkResponse(response); sendSuccessResultCallback(o, finalCallback); } catch (Exception e) { sendFailResultCallback(call, e, finalCallback); } } }); } public void sendFailResultCallback(final Call call, final Exception e, final Callback callback) { if (callback == null) return; mDelivery.post(new Runnable() { @Override public void run() { callback.onError(call, e); callback.onAfter(); } }); } public void sendSuccessResultCallback(final Object object, final Callback callback) { if (callback == null) return; mDelivery.post(new Runnable() { @Override public void run() { callback.onResponse(object); callback.onAfter(); } }); } public void cancelTag(Object tag) { for (Call call : mOkHttpClient.dispatcher().queuedCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } for (Call call : mOkHttpClient.dispatcher().runningCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } } public void setCertificates(InputStream... certificates) { mOkHttpClient = getOkHttpClient().newBuilder() .sslSocketFactory(HttpsUtils.getSslSocketFactory(certificates, null, null)) .build(); } public void setConnectTimeout(int timeout, TimeUnit units) { mOkHttpClient = getOkHttpClient().newBuilder() .connectTimeout(timeout, units) .build(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值