网络请求无论在程序哪里发起,我们都是那些代码,只是参数不同罢了,所以我们可以封装一个HttpUtils类,在其中将重复的代码都写好,只需要我们传入的参数不同,我们就可以发起不同的网络请求了。
其实就是网络请求一般都是耗时操作,所以我们需要另开线程去访问网络,但是如果我们在访问网络的方法中开启新的线程,我们就不得而知这个新开的线程是否获取的数据,可能在数据还没返回之前,我们访问网络的方法就已经执行完毕了,如果是这样的话,可能就无法返回相应的数据了。(我也有点晕了,似懂非懂,但是就是感觉这样实现的方法很巧妙,请继续往下看)
为了避免上面的问题,我们可以定义一个接口,在其中写好两个方法,一个对应成功返回数据,一个对应访问出错。
同时两个方法的参数就是我们访问网络所得的数据
代码如下:
public class HttpUtils {
public interface HttpBackData {
public void onFinish(String data );
public void onError(String data);
}
public static void sendHttpRequest(final String urls, final HttpBackData httpBackData) {
new Thread(new Runnable() {
@Override
public void run() {
URL url;
HttpURLConnection conn=null;
try {
url = new URL(urls);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setDoInput(true);
conn.setDoOutput(true);
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String data = "";
String temp = br.readLine();
while (temp != null) {
data += temp;
temp = br.readLine();
}
br.close();
httpBackData.onFinish(data);
} catch (Exception e) {
e.printStackTrace();
httpBackData.onError("访问出错");
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
}).start();
}
}
- 我们的参数中多了一个接口的实例,而且成功访问数据之后,我们就调用onfinish()方法
- 失败之后,我们就调用onError()方法
- 那么我们再来看主活动中的代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button button;
private TextView textView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
button= (Button) findViewById(R.id.button);
button.setOnClickListener(this);
textView= (TextView) findViewById(R.id.textView);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button:
String urls="http://www.baidu.com";
HttpUtils.sendHttpRequest(urls, new HttpUtils.HttpBackData() {
@Override
public void onFinish(String data) {
Log.d("***",data);
}
@Override
public void onError(String data) {
Log.d("***",data);
}
});
break;
}
}
}
可以看到,我们在点击按钮的实践中,发起了网络请求,然后必须实现接口的方法,这样就可以由方法的参数获取到网络请求的数据了。
需要注意一点,onFinish()和onError()方法最终还是在子线程中运行的,以此如果需要更新UI,我们还是需要拥戴异步消息处理机制
其实前面已经写过一片过于观察者模式的博客,不过那时候是在Java中用到的,不过大同小异,如果有兴趣还可以再看看看这篇博客 观察者模式