目前最新版本的是okhttp:3.4.1,也称为Okhttp3。
OkHttp是一个精巧的网络请求库,不仅在接口封装做的简单易用,在底层实现上也自成一派。比起原生的HttpURLConnection有过之而无不及,现在已经成为广大开发者的首选网络通讯库。
dependencies {
...
compile 'com.squareup.okhttp3:okhttp:3.4.1'
...
}
Android Studio添加上述依赖后会自动下载两个库,一个是Okhttp,另一个是Okio。
之前写了一篇博客简单讲解了MVP模式的使用,MVP模式&简单实例,实现的效果不明显,MVP模式的好处也没有体现。
今天结合Okhttp3框架,实现多种网络请求,并从侧面表现MVP模式数据传递的巧妙之处。
主要包含以下几个内容:
public class OkHttp3 {
private static OkHttpClient client = new OkHttpClient();
public static OkHttpClient getClient() {
return client;
}
}
Request request = new Request.Builder().url(url).build();
RequestBody requestBody = new FormBody.Builder().add("key","value").build();
Request request = new Request.Builder().post(formBody).url(url).build();
Response response = client.newCall(request).exectue();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败时的事物处理
}
@Override
public void onResponse(Call call, Response response) {
//成功时的事物处理
}
});
事实上Android开发过程中在主线程进行网络同步请求是一件极其危险的事情,如果耗时太多会造成主线程阻塞,进而进程崩溃,所以本文的所有方法都采用异步请求。
/**
* 创建新线程实现同步get请求
* @param context
* @param url
* @return
* @throws Exception
*/
public String getSysn(final Context context, final String url) throws Exception {
FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
String result = response.body().string();
return result;
}
});
new Thread(task).start();
return task.get();
}
response.body().string();//String类型数据
response.body().byteStream();//文件输入流数据
response.body().bytes();//二进制字节数组
具体获取的数据,要看服务器返回的数据类型。
如果你仔细看完Okhttp的具体用法,那么看懂Model类就不是难事。
/**
* 方法模型层
* Created by D&LL on 2017/3/13.
*/
public class Model {
private static Model instance = new Model();//单例
public static Model getInstance() {
return instance;
}
private ProgressDialog dialog;//显示下载的进度条
public OkHttpClient client = OkHttp3.getClient();
/**
* 异步get请求
* 使用ICallBack接口传递返回数据
* @param context
* @param url
* @return
* @throws Exception
*/
public void getSynchronized(final Context context, final String url, final ICallBack callback) {
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.result(e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
callback.result(response.body().string());
} else {
callback.result("请求失败!");
}
}
});
}
/**
* post方式提交Map
* 使用ICallBack接口传递返回数据
* @param url
* @param map
* @return
* @throws Exception
*/
public void postMap(final Context context, final String url, Map<String, String> map, final ICallBack callback) {
FormBody.Builder builder = new FormBody.Builder();
if (map != null) {
//增强for循环遍历
for (Map.Entry<String, String> entry : map.entrySet()) {
builder.add(entry.getKey(), entry.getValue());
}
}
FormBody formBody = builder.build();
Request request = new Request.Builder().post(formBody).url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.result(e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
callback.result(response.body().string());
} else {
callback.result("请求失败!");
}
}
});
}
/**
* 异步下载文件
* BitmapCallBack接口进行数据传递
* @param context
* @param url
* @param name
*/
public void downAsynFile(final Context context, String url, final String name, final BitmapCallBack callback) {
dialog = DialogUtil.getProgressDialog(context);
dialog.show();
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println(e);
}
@Override
public void onResponse(Call call, Response response) {
if (response.isSuccessful()) {
InputStream inputStream = response.body().byteStream();//获取文件输入流
Bitmap bitmap = FileUtil.saveFile(name, inputStream);//获取的流进行文件操作
callback.imgBitmap(bitmap);
System.out.println("下载成功!");
} else {
System.out.println("下载失败!");
}
response.close();//下载文件耗时较久,完成后需要手动关闭请求
dialog.dismiss();
}
});
}
}
public interface ICallBack {
void result(String s);
}
public interface BitmapCallBack {
void imgBitmap(Bitmap bitmap);
}
//视图接口层,与视图进行数据传输的接口
public interface MainView {
void getView(String s);
void postView(String s);
void imgView(Bitmap bitmap);
}
的形式存储数据的,而一般来说我们的请求参数参数都是一个key对应一个value,因此只需要用循环遍历add()请求参数即可。//增强for循环遍历
for (Map.Entry<String, String> entry : map.entrySet()) {
builder.add(entry.getKey(), entry.getValue());
}
/**
* 方法操作层
* Created by D&LL on 2017/3/13.
*/
public class MainPresenter {
private Model model = Model.getInstance();
private MainView mainView;
private Context context;
public MainPresenter(Context context, MainView mainView) {
this.context = context;
this.mainView = mainView;
}
public void getRequest(String url) {//get异步请求调用
model.getSynchronized(context, url, new ICallBack() {
@Override
public void result(String s) {
System.out.println(s);
mainView.getView(s);
}
});
}
public void postMap(String url, Map<String, String> map) {//post异步请求
model.postMap(context, url, map, new ICallBack() {
@Override
public void result(String s) {
System.out.println(s);
mainView.postView(s);
}
});
}
public void downFile(String url,String name){//异步下载
model.downAsynFile(context, url, name, new BitmapCallBack() {
@Override
public void imgBitmap(Bitmap bitmap) {
mainView.imgView(bitmap);
}
});
}
}
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/get"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:textSize="20sp" />
<TextView
android:id="@+id/post"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:textSize="20sp" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="down_img" />
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitXY" />
LinearLayout>
Activity:
public class MainActivity extends AppCompatActivity implements MainView {
String geturl = "http://p.3.cn/prices/mgets?skuIds=J_954086&type=1";//京东获取单个商品价格接口:
String posturl = "http://gc.ditu.aliyun.com/geocoding";//阿里云根据地区名获取经纬度接口
@BindView(R.id.button)
Button button;
@BindView(R.id.get)
TextView get;
@BindView(R.id.post)
TextView post;
@BindView(R.id.img)
ImageView img;
private MainPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);//butterknife
initData();
}
private void initData() {
Map<String, String> map = new HashMap<>();
map.put("a", "苏州市");
presenter = new MainPresenter(this, this);
presenter.getRequest(geturl);
presenter.postMap(posturl, map);
}
@OnClick(R.id.button)
public void onClick() {
presenter.downFile("http://images.csdn.net/20150817/1.jpg", "demo.jpg");//下载并显示图片
}
@Override
public void getView(final String s) {//显示get请求返回值
runOnUiThread(new Runnable() {
@Override
public void run() {
get.setText(s);
}
});
}
@Override
public void postView(final String s) {//显示post请求返回值
runOnUiThread(new Runnable() {
@Override
public void run() {
post.setText(s);
}
});
}
@Override
public void imgView(final Bitmap bitmap) {//显示下载的图片
runOnUiThread(new Runnable() {
@Override
public void run() {
img.setImageBitmap(bitmap);
}
});
}
}
runOnUiThread(new Runnable(){ @Override
public void run() {
}});
private Handler mHandler;
private TextView mTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mTxt = (TextView) findViewById(R.id.txt);
mHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
mTxt.setText((String) msg.obj);
}
};
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("https://github.com").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Message msg = new Message();
msg.what=0;
msg.obj = response.body().string();
mHandler.sendMessage(msg);
}
});
}
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
CSDN下载: https://download.csdn.net/download/demonliuhui/10755566
GitHub下载:https://github.com/MyAndroidDemo/OkhttpMVP
API免费测试接口:http://www.bejson.com/knownjson/webInterface/
http://www.tuicool.com/articles/6FjAJnV
http://www.qingpingshan.com/rjbc/az/110232.html
http://blog.csdn.net/lmj623565791/article/details/47911083