Android 使用接口回掉实现线程间数据传递

来源:互联网 发布:精灵对抗赛数据 编辑:程序博客网 时间:2024/05/23 17:58

Java的接口回掉机制是个好东西,无论是线程之间的数据传递还是Activity与Fragment之间的数据传递都可能会用到接口回掉,于是做了一个关于线程之间的接口回掉的小demo,帮助我们简单理解一下接口回掉机制。

github项目源码 https://github.com/MQLX1004/Myhub/tree/master/NetworkTest

demo的大体意思就是从一个网址中获取信息,然后显示到TextView中

网络请求部分需要开启一个子线程,更改UI部分需要在主线程中进行,这样就产生了线程之间如何传递信息的问题,有些人可能会说使用Handler传递一个Message就可以,但是如果我们另外写一个类,这个类专门处理网络请求,就不能使用Handler传递Message了。这时候最好的解决方法就是使用接口回掉。

首先看看我们的界面设计的,界面很简单,就是一个Button一个TextView,点击Button的时候就会开启子线程发送网络请求,然后在TextView中显示请求结果

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:id="@+id/button"        android:text="@string/app_name"        android:layout_width="match_parent"        android:layout_height="50dp"/>    <TextView        android:id="@+id/textView"        android:hint="@string/app_name"        android:layout_width="match_parent"        android:layout_height="match_parent"/></LinearLayout>
既然是接口回掉机制就得有一个接口,我们先看看接口是如何写的吧,随后使用的时候就知道它是怎么用的了。

接口中有两个方法,onFinish方法中的参数为请求URL成功后返回的数据。

onError方法中的参数为请求URL失败后返回的错误信息。

public interface HttpCallback {    //获取成功调用    void onFinish(String response);    //获取失败调用    void onError(Exception e);}
然后看一下专门处理网络请求的类,该类只有一个方法,该方法设置为静态方法,这样以后发送网络请求的时候可以直接通过类名调用该方法,方法有两个参数,一个是要请求的URL,一个是刚刚定义的接口。这个接口在调用此方法时已经被重写了,稍后会见到此接口的重写。

public class HttpUtil {    public static void sendHttpRequest(final String address,final HttpCallback listener) {        new Thread(new Runnable() {//开启子线程            @Override            public void run() {                HttpURLConnection connection = null;                try {                    URL url = new URL(address);                    connection = (HttpURLConnection) url.openConnection();                    connection.setRequestMethod("GET");//设置请求方式                    connection.setConnectTimeout(8000);//设置链接超时时间                    connection.setReadTimeout(8000);//设置读取超时时间                    connection.setDoInput(true);                    connection.setDoOutput(true);                    InputStream in = connection.getInputStream();                    BufferedReader reader = new BufferedReader(new                            InputStreamReader(in));                    StringBuilder response = new StringBuilder();                    String line;                    while ((line = reader.readLine()) != null) {                        response.append(line);                    }                    listener.onFinish(response.toString());//接口回掉                } catch (Exception e) {                    e.printStackTrace();                    listener.onError(e);//接口回掉                } finally {                    if (connection != null) {                        connection.disconnect();//关闭连接                    }                }            }        }).start();    }}
现在我们的接口也有了,专门处理网络请求的类也有了,只剩下进行网络请求的类了,在这里这个类为MainActivity.java 我们需要在这个类中调用刚刚那个静态类,并重写我们的接口,在onFinish方法中写请求成功后对返回信息的处理逻辑,在onError方法中写请求失败后对返回错误的处理逻辑。

这里也会用到Handler来传递Message,我们这里将发起网络请求的代码独立到一个类中,降低了代码的耦合度,也会使网络请求更加简便。

import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity {    public static final int SHOW=0;    private Button mButton;    private TextView mTextView;    private Handler mHandler=new Handler(){        @Override        public void handleMessage(Message msg) {            switch (msg.what){                case SHOW:                    String respone=(String)msg.obj;                    mTextView.setText(respone);            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mButton=(Button)findViewById(R.id.button);        mTextView=(TextView)findViewById(R.id.textView);        mButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                sendrequset();//点击Button后发起网络请求            }        });    }    private void sendrequset(){        HttpUtil.sendHttpRequest("http://10.0.2.2:8080/android/Json.json", new HttpCallback() {//调用网络请求静态类并重写接口中的方法            @Override            public void onFinish(String response) {                Message message=new Message();                message.what=SHOW;                message.obj=response;                mHandler.sendMessage(message);            }            @Override            public void onError(Exception e) {                e.printStackTrace();                Message message=new Message();                message.what=SHOW;                message.obj="获取失败";                mHandler.sendMessage(message);            }        });    }}

这样整个代码跑起来的大体流程就是:当点击Button后发起网络请求,调用网络请求静态方法,往该方法中传入两个参数,一个是要请求的URL,一个是接口重写后的一个对象,当网络请求成功时调用这个对象的onFinish方法,当网络请求失败时调用这个对象中的onError方法。

如果想要传输图片,只需要在获取InputStream之后转换为Bitmap即可,这样写:

InputStream in = connection.getInputStream();Bitmap bitmap= BitmapFactory.decodeStream(in);
然后改一下接口的onFinish方法中的参数类型,将Stirng改成Bitmap类型,再改一下重写onFinish中的处理逻辑代码就可以了。

public interface HttpCallback {    //获取成功调用    void onFinish(Bitmap response);    //获取失败调用    void onError(Exception e);}

@Overridepublic void onFinish(Bitmap response) {    Message message=new Message();    message.what=SHOW;    message.obj=response;    mHandler.sendMessage(message);}
然后改一下Handler中的处理代码:

private Handler mHandler=new Handler(){    @Override    public void handleMessage(Message msg) {        switch (msg.what){            case SHOW:                Bitmap respone=(Bitmap) msg.obj;                //mTextView.setText(respone);                mImageView.setImageBitmap(respone);        }    }};
这样就完成了图片的传输。

3 0
原创粉丝点击