1.先在model中添加所需要的依赖,主要有:
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
compile 'com.google.code.gson:gson:2.8.2'
没有使用过ButterKnife的童鞋可参考https://blog.csdn.net/dreamlivemeng/article/details/51261170和
https://blog.csdn.net/pigdreams/article/details/65448149(请注意:android studio3.1及其以上版本不兼容 Butterknife8.8.1)。
2.Activity代码实现@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
(1)父类activity
package com.mobile.administrator.appmine09.base;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
/**
* Created by Administrator on 2018/9/11 0011.
*/
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected abstract void initData();
protected abstract void initView();
protected abstract void showToast(String msg);
protected abstract void runToUIThread(String dataStr, String showStr);
}
(2)activity
package com.mobile.administrator.appmine09.activity;
import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.mobile.administrator.appmine09.R;
import com.mobile.administrator.appmine09.base.BaseActivity;
import com.mobile.administrator.appmine09.bean.ReasonBean;
import com.mobile.administrator.appmine09.callback.LoadCallback;
import com.mobile.administrator.appmine09.manager.Okhttp3Manager;
import com.mobile.administrator.appmine09.utils.MyLogUtil;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class MainActivity extends BaseActivity implements View.OnClickListener {
@BindView(R.id.tev_get_sync)
TextView tevGetSync;
@BindView(R.id.tev_get_async)
TextView tevGetAsync;
@BindView(R.id.tev_post_sync)
TextView tevPostSync;
@BindView(R.id.tev_post_async)
TextView tevPostAsync;
@BindView(R.id.tev_data)
TextView tevData;
private Okhttp3Manager manager;
public static final String GET_URL = "http://v.juhe.cn/toutiao/index?type=历史&key=d05b58fa6901ad9bed77a1ef08bd6ccb";
public static final String POST_URL = "http://v.juhe.cn/toutiao/index";
private String url2 = "https://baike.baidu.com/pic/%E6%AD%A6%E7%94%B0%E7%8E%B2%E5%A5%88/16824602/0/32fa828ba61ea8d3ec4ad9129e0a304e251f58bf?fr=lemma&ct=single#aid=0&pic=32fa828ba61ea8d3ec4ad9129e0a304e251f58bf";
private Map<String, String> map = new HashMap<>();
private ReasonBean reasonBean;
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initData();
initView();
}
@Override
protected void initData() {
if (Build.VERSION.SDK_INT >= 23) {
String[] mPermissionList = new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CALL_PHONE,
Manifest.permission.READ_LOGS,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.SET_DEBUG_APP,
Manifest.permission.SYSTEM_ALERT_WINDOW,
Manifest.permission.GET_ACCOUNTS,
Manifest.permission.WRITE_APN_SETTINGS};
ActivityCompat.requestPermissions(this, mPermissionList, 123);
}
manager = Okhttp3Manager.getInstance(this);
map.put("type", "娱乐");
map.put("key", "d05b58fa6901ad9bed77a1ef08bd6ccb");
}
@Override
protected void initView() {
tevGetSync.setOnClickListener(this);
tevGetAsync.setOnClickListener(this);
tevPostSync.setOnClickListener(this);
tevPostAsync.setOnClickListener(this);
}
@Override
protected void showToast(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
/**
* 请求返回的数据都是在子线程,要把它运行到主线程
* @param dataStr
* @param showStr
*/
@Override
protected void runToUIThread(final String dataStr, final String showStr) {
runOnUiThread(new Runnable() {
@Override
public void run() {
showToast(showStr);
if (!"".equals(dataStr)) {
reasonBean = manager.fromJson(1.0, dataStr, ReasonBean.class);
MyLogUtil.i(TAG, "dataStr*****" + dataStr);
MyLogUtil.i(TAG, "reasonBean.toString()*****" + reasonBean.toString());
tevData.setText(dataStr);
} else {
tevData.setText(dataStr);
}
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tev_get_sync:
manager.getSyncOkHttp(GET_URL, new LoadCallback() {
@Override
public void getSuccess(final String dataStr) {
runToUIThread(dataStr, "请求成功!");
}
@Override
public void getFailed() {
runToUIThread("", "请求成功!");
showToast("请求失败!");
}
});
break;
case R.id.tev_get_async:
manager.getAsyncOkHttp(GET_URL, map, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
runToUIThread("", "请求失败!");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
runToUIThread(response.body().string(), "请求成功!");
}
});
break;
case R.id.tev_post_sync:
manager.postSyncOkhttp(POST_URL, map, new LoadCallback() {
@Override
public void getSuccess(String dataStr) {
runToUIThread(dataStr, "请求成功!");
}
@Override
public void getFailed() {
runToUIThread("", "请求失败!");
}
});
break;
case R.id.tev_post_async:
manager.postAsyncOkhttp(POST_URL, map, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
runToUIThread("", "请求失败!");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
runToUIThread(response.body().string(), "请求成功!");
}
});
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
3.Okhttp3代码实现&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
package com.mobile.administrator.appmine09.manager;
import android.content.Context;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.mobile.administrator.appmine09.callback.LoadCallback;
import com.mobile.administrator.appmine09.utils.MyLogUtil;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by Administrator on 2018/9/8 0008.
*/
public class Okhttp3Manager {
private OkHttpClient client;
private static Okhttp3Manager manager;
private Gson gson;
private static final String TAG = Okhttp3Manager.class.getSimpleName();
/**
* 单例模式,所以构造函数私有化
*/
private Okhttp3Manager() {
//创建OkHttpClient对象
client = new OkHttpClient.Builder()
.connectTimeout(5 * 1000, TimeUnit.MILLISECONDS) //链接超时
.readTimeout(10 * 1000, TimeUnit.MILLISECONDS) //读取超时
.writeTimeout(10 * 1000, TimeUnit.MILLISECONDS) //写入超时
.build();
gson = new GsonBuilder().setVersion(1.0)
.create();
}
/**
* 线程安全的单例模式,整个项目中只有一个okhttp3实例
* @param context
* @return
*/
public static Okhttp3Manager getInstance(Context context) {
if (manager == null) {
synchronized (Okhttp3Manager.class) {
if (manager == null) {
manager = new Okhttp3Manager();
}
}
}
return manager;
}
/**
* 同步请求 写了一个接口把值放入
*/
public void getSyncOkHttp(String url, final LoadCallback loadCallback) {
//调用ok的get请求
Request request = new Request.Builder()
.get()
.url(url)
.build();
final Call call = client.newCall(request);
//同步execute
//同步请求
//同步是耗时的
//同步execute需要开启子线程
new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = call.execute();
if (response.isSuccessful()) {
String string = response.body().string();
//调用者只需要实现provide方法就能拿到这个String了
loadCallback.getSuccess(string);
} else {
loadCallback.getFailed();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* get拼接传值方法(异步请求)
*
* @param url ?username=xxxx&password=xxx
*/
public void getAsyncOkHttp(String url, Map<String, String> map, Callback callback) {
StringBuffer sb = new StringBuffer();
String string = "";
String result = "";
//当用户传入null或者传了一个空的map
if (map != null && !map.isEmpty()) {
for (Map.Entry<String, String> entry : map.entrySet()) {
if (sb == null) {
// sb = new StringBuffer ();
sb.append("?");
} else {
//拼接好的网站去掉最后一个“&”符号
sb.append("&");
}
sb.append(entry.getKey() + "=" + entry.getValue());
}
}
if (sb.toString() != null) {
string = sb.toString();
MyLogUtil.i(TAG, string);
result = url + string;
MyLogUtil.i(TAG, result);
}
Request request = new Request.Builder()
.get() //声明我是get请求,如果不写默认就是get
.url(string == "" ? url : result)//声明网站访问的网址
.build();//创建Request
Call call = client.newCall(request);
//同步execute,异步enqueue
//这里的同步是耗时的
//而且OK 也没有为我们开启子线程
// 如果你用同步方法的话,需要开启子线程
call.enqueue(callback);
}
/**
* Post请求(同步请求)
* <p>
* FormBody:用来提交一个不包涵文件的参数
* 第
*/
public void postSyncOkhttp(String url, Map<String, String> map, final LoadCallback loadCallback) {
//上传文字格式 数据的传输,区别于多媒体输出
FormBody.Builder formbody = new FormBody.Builder();
if (map != null && !map.isEmpty()) {
//上传参数
for (String key : map.keySet()) {
formbody.add(key, map.get(key));
}
//创建请求体
FormBody body = formbody.build();
Request request = new Request.Builder()
.post(body)
.url(url)
.build();
final Call call = client.newCall(request);
//同步请求方式
//同步execute
//同步请求
//同步是耗时的
//同步execute需要开启子线程
new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = call.execute();
if (response.isSuccessful()) {
String string = response.body().string();
//调用者只需要实现provide方法就能拿到这个String了
loadCallback.getSuccess(string);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} else {
//创建请求体
FormBody body = formbody.build();
Request request = new Request.Builder()
.post(body)
.url(url)
.build();
final Call call = client.newCall(request);
//同步请求方式
//同步execute
//同步请求
//同步是耗时的
//同步execute需要开启子线程
new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = call.execute();
if (response.isSuccessful()) {
String string = response.body().string();
//调用者只需要实现provide方法就能拿到这个String了
loadCallback.getSuccess(string);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
/**
* Post请求(异步请求)
* <p>
* FormBody:用来提交一个不包涵文件的参数
* 第
*/
public void postAsyncOkhttp(String url, Map<String, String> map, Callback callBack) {
//上传文字格式 数据的传输,区别于多媒体输出
FormBody.Builder formbody = new FormBody.Builder();
if (map != null && !map.isEmpty()) {
//上传参数
for (String key : map.keySet()) {
formbody.add(key, map.get(key));
}
//创建请求体
FormBody body = formbody.build();
Request request = new Request.Builder()
.url(url)
.post(body)//请求体
.build();
Call call = client.newCall(request);
//异步请求方式
call.enqueue(callBack);
} else {
//创建请求体
FormBody body = formbody.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Call call = client.newCall(request);
//异步请求方式
call.enqueue(callBack);
}
}
/**
* MultipartBody:用来提交包涵文件的参数(异步请求)
*
* @param path :路径
* @param map :普通参数
* @param img :提交文件的关键字
* @param imgPath :提交文件的路径
*/
public void postFileOkhttp(String path, HashMap<String, String> map, String img, String imgPath, Callback callBack) {
MultipartBody.Builder requestBody = new MultipartBody.Builder();
if (map != null && !map.isEmpty()) {
//上传参数
for (String key : map.keySet()) {
requestBody.addFormDataPart(key, map.get(key));
}
File file = new File(imgPath);
requestBody.addFormDataPart(img, file.getPath()
, RequestBody.create(MediaType.parse("image/png"), file));
Request request = new Request.Builder()
.post(requestBody.build())
.url(path)
.build();
Call call = client.newCall(request);
call.enqueue(callBack);
} else {
File file = new File(imgPath);
requestBody.addFormDataPart(img, file.getPath()
, RequestBody.create(MediaType.parse("image/png"), file));
Request request = new Request.Builder()
.post(requestBody.build())
.url(path)
.build();
Call call = client.newCall(request);
call.enqueue(callBack);
}
}
/**
* 用于将指定的Object对象序列化成相应的JSON数据
*
* @param version
* @param object
* @return
*/
public String toJson(double version, Object object) {
return gson.toJson(object);
}
/**
* 用于将JsonElement对象(可以是JsonObject、JsonArray等)转换成JSON数据
*
* @param version
* @param jsonElement
* @return
*/
public String toJson(double version, JsonElement jsonElement) {
String str = gson.toJson(jsonElement);
return str;
}
/**
* @param jsonStr
* @param classOfT
* @param <T>
* @return
*/
public <T> T fromJson(double version, String jsonStr, Class<T> classOfT) {
return gson.fromJson(jsonStr, classOfT);
}
}
4.自定义接口回调代码实现&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
package com.mobile.administrator.appmine09.callback;
/**
* Created by ${周康} on ${Study}.
*/
public interface LoadCallback {
void getSuccess(String dataStr);
void getFailed();
}
5.实体类代码实现&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
package com.mobile.administrator.appmine09.bean;
import java.util.List;
/**
* Created by Administrator on 2018/9/9 0009.
*/
public class ReasonBean {
private String reason;
private ResultBean result;
private int error_code;
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public ResultBean getResult() {
return result;
}
public void setResult(ResultBean result) {
this.result = result;
}
public int getError_code() {
return error_code;
}
public void setError_code(int error_code) {
this.error_code = error_code;
}
public static class ResultBean {
private String stat;
private List<DataBean> data;
public String getStat() {
return stat;
}
public void setStat(String stat) {
this.stat = stat;
}
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
public static class DataBean {
private String uniquekey;
private String title;
private String date;
private String category;
private String author_name;
private String url;
private String thumbnail_pic_s;
private String thumbnail_pic_s02;
private String thumbnail_pic_s03;
public String getUniquekey() {
return uniquekey;
}
public void setUniquekey(String uniquekey) {
this.uniquekey = uniquekey;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getAuthor_name() {
return author_name;
}
public void setAuthor_name(String author_name) {
this.author_name = author_name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getThumbnail_pic_s() {
return thumbnail_pic_s;
}
public void setThumbnail_pic_s(String thumbnail_pic_s) {
this.thumbnail_pic_s = thumbnail_pic_s;
}
public String getThumbnail_pic_s02() {
return thumbnail_pic_s02;
}
public void setThumbnail_pic_s02(String thumbnail_pic_s02) {
this.thumbnail_pic_s02 = thumbnail_pic_s02;
}
public String getThumbnail_pic_s03() {
return thumbnail_pic_s03;
}
public void setThumbnail_pic_s03(String thumbnail_pic_s03) {
this.thumbnail_pic_s03 = thumbnail_pic_s03;
}
@Override
public String toString() {
return "DataBean{" +
"uniquekey='" + uniquekey + '\'' +
", title='" + title + '\'' +
", date='" + date + '\'' +
", category='" + category + '\'' +
", author_name='" + author_name + '\'' +
", url='" + url + '\'' +
", thumbnail_pic_s='" + thumbnail_pic_s + '\'' +
", thumbnail_pic_s02='" + thumbnail_pic_s02 + '\'' +
", thumbnail_pic_s03='" + thumbnail_pic_s03 + '\'' +
'}';
}
}
@Override
public String toString() {
return "ResultBean{" +
"stat='" + stat + '\'' +
", data=" + data +
'}';
}
}
@Override
public String toString() {
return "ReasonBean{" +
"reason='" + reason + '\'' +
", result=" + result +
", error_code=" + error_code +
'}';
}
}
6.工具类代码实现&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
扫描二维码关注公众号,回复:
3154413 查看本文章
package com.mobile.administrator.appmine09.utils;
import android.util.Log;
/**
* Created by Administrator on 2018/4/26 0026.
*/
public class MyLogUtil {
//规定每段显示的长度
private static int LOG_MAXLENGTH = 2000;
public static void i(String TAG, String msg) {
int strLength = msg.length();
int start = 0;
int end = LOG_MAXLENGTH;
for (int i = 0; i < 100; i++) {
//剩下的文本还是大于规定长度则继续重复截取并输出
if (strLength > end) {
Log.i(TAG + i, msg.substring(start, end));
start = end;
end = end + LOG_MAXLENGTH;
} else {
Log.i(TAG, msg.substring(start, strLength));
break;
}
}
}
}
7.布局文件代码实现&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mobile.administrator.appmine09.activity.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:layout_gravity="center">
<TextView
android:id="@+id/tev_get_sync"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:gravity="center"
android:layout_gravity="center"
android:text="getSync"
android:textColor="@color/colorPrimary"
android:textSize="20sp" />
<TextView
android:id="@+id/tev_get_async"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:gravity="center"
android:layout_gravity="center"
android:text="getASync"
android:textColor="@color/colorPrimary"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:layout_gravity="center">
<TextView
android:id="@+id/tev_post_sync"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:gravity="center"
android:layout_gravity="center"
android:text="postSync"
android:textColor="@color/colorPrimary"
android:textSize="20sp" />
<TextView
android:id="@+id/tev_post_async"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:gravity="center"
android:layout_gravity="center"
android:text="postASync"
android:textColor="@color/colorPrimary"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:id="@+id/tev_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="@color/colorPrimary"
android:textSize="18sp" />
</ScrollView>
</LinearLayout>
</LinearLayout>
8.最后别忘了添加权限&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
<uses-permission android:name="android.permission.INTERNET"/>