Okhttp解析Gson資料並且展示到recyclerView
阿新 • • 發佈:2019-01-01
1、這篇文章主要應用的是Okhttp請求網路資料解析Gson,判斷網路,沒有網路跳轉到設定介面,然後通過XRecyclerView展示到頁面中。並且可以實現全域性捕獲異常,載入圖片實現屬性動畫漸變的效果。
2、匯入依賴
compile 'com.squareup.okhttp:okhttp:2.4.0' compile 'io.github.openfeign:feign-gson:9.5.1' compile 'com.github.bumptech.glide:glide:3.8.0' compile 'com.jcodecraeer:xrecyclerview:1.3.2'這四個依賴分別是okhttp的依賴、Gson的依賴、圖片載入Glide的依賴、XrecyclerView的依賴
3、配置許可權
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET"></uses-permission>這兩個許可權分別是編寫的許可權跟聯網的許可權
4、MainActivity中的佈局,只需要佈一個XrecyclerView的佈局就可以了
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"5、MainActicity中的資料android:layout_width="match_parent" android:layout_height="match_parent" > <com.jcodecraeer.xrecyclerview.XRecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" ></com.jcodecraeer.xrecyclerview.XRecyclerView> </RelativeLayout>
import android.animation.ObjectAnimator; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; import com.google.gson.Gson; import com.jcodecraeer.xrecyclerview.XRecyclerView; import com.squareup.okhttp.Callback; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import java.io.IOException; import java.util.List; public class MainActivity extends AppCompatActivity { private List<Bean.DataBean> list; private XRecyclerView recycler; private String URL = "http://www.yulin520.com/a2a/impressApi/news/mergeList?sign=C7548DE604BCB8A17592EFB9006F9265&pageSize=20&gender=2&ts=1871746850&page="; private int page = 1;//設定首先展示的頁面是第一頁 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); String u = (String) msg.obj; Gson gson = new Gson(); Bean bean = gson.fromJson(u, Bean.class); list = bean.getData(); //設定佈局管理器 recycler.setLayoutManager(new LinearLayoutManager(MainActivity.this)); //設定介面卡 recycler.setAdapter(new MyAdapter()); //分頁加的 recycler.setLoadingListener(new XRecyclerView.LoadingListener() { @Override //下拉重新整理 public void onRefresh() { page = 1; list.clear(); jiexi(); recycler.refreshComplete(); } @Override //上拉載入 public void onLoadMore() { page++; jiexi(); Toast.makeText(MainActivity.this, "載入更多", Toast.LENGTH_LONG).show(); recycler.loadMoreComplete(); } }); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //判斷網路 checkNetwork(); //找控制元件 initData(); //解析資料 jiexi(); if (!checkNetwork()) { Toast.makeText(this, "沒有網路", Toast.LENGTH_LONG).show(); Intent intent = new Intent("android.settings.WIRELESS_SETTINGS"); startActivity(intent); return; } } private void jiexi() { OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder() .url(URL) .build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(Response response) throws IOException { String string = response.body().string(); Log.i("aaa", "run: " + string); Message message = new Message(); message.obj = string; handler.sendMessage(message); } }); } //找到控制元件 private void initData() { recycler = (XRecyclerView) findViewById(R.id.recycler); } private boolean checkNetwork() { ConnectivityManager conn = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo net = conn.getActiveNetworkInfo(); if (net != null && net.isConnected()) { return true; } return false; } class MyAdapter extends XRecyclerView.Adapter<MyAdapter.MyViewHolder> { @Override //繫結佈局 public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); MyViewHolder viewHolder = new MyViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.name.setText(list.get(position).getTitle()); // holder.old.setText(list.get(position).getUserAge()); Glide.with(MainActivity.this).load(list.get(position).getImg()).into(holder.image); holder.desc.setText(list.get(position).getIntroduction()); holder.job.setText(list.get(position).getOccupation()); //新增屬性動畫,實現漸變效果。 ObjectAnimator// .ofFloat(holder.image, "alpha",0.0F,1f)// .setDuration(2000)// .start(); } @Override public int getItemCount() { return list.size(); } class MyViewHolder extends XRecyclerView.ViewHolder { public TextView name; public TextView old; public TextView desc; public ImageView image; public TextView job; public MyViewHolder(View itemView) { super(itemView); name = itemView.findViewById(R.id.name); old = itemView.findViewById(R.id.old); desc = itemView.findViewById(R.id.desc); image = itemView.findViewById(R.id.image); job = itemView.findViewById(R.id.job); } } } }6、藉助Formate建立一個Bean類
7、全域性異常的獲取類。記得要在Application中申明這個類
android:name=".MainApplication"
貼上兩個包進去。
7.1
import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.os.Environment; import android.os.Looper; import android.util.Log; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; public class CrashHandler implements Thread.UncaughtExceptionHandler { private static final String TAG = "CrashHandler"; private Thread.UncaughtExceptionHandler mDefaultHandler;// 系統預設的UncaughtException處理類 private static CrashHandler INSTANCE = new CrashHandler();// CrashHandler例項 private Context mContext;// 程式的Context物件 private Map<String, String> info = new HashMap<String, String>();// 用來儲存裝置資訊和異常資訊 private SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd-HH-mm-ss");// 用於格式化日期,作為日誌檔名的一部分 /** * 保證只有一個CrashHandler例項 */ private CrashHandler() { } /** * 獲取CrashHandler例項 ,單例模式 */ public static CrashHandler getInstance() { return INSTANCE; } /** * 初始化 * * @param context */ public void init(Context context) { mContext = context; mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 獲取系統預設的UncaughtException處理器 Thread.setDefaultUncaughtExceptionHandler(this);// 設定該CrashHandler為程式的預設處理器 } /** * 當UncaughtException發生時會轉入該重寫的方法來處理 */ public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) { // 如果自定義的沒有處理則讓系統預設的異常處理器來處理 mDefaultHandler.uncaughtException(thread, ex); } else { try { Thread.sleep(3000);// 如果處理了,讓程式繼續執行3秒再退出,保證檔案儲存並上傳到伺服器 } catch (InterruptedException e) { e.printStackTrace(); } // 退出程式 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } /** * 自定義錯誤處理,收集錯誤資訊 傳送錯誤報告等操作均在此完成. * * @param ex 異常資訊 * @return true 如果處理了該異常資訊;否則返回false. */ public boolean handleException(Throwable ex) { if (ex == null) return false; new Thread() { public void run() { Looper.prepare(); Toast.makeText(mContext, "出現閃退了正在把日誌儲存到sdcard crash目錄下", Toast.LENGTH_LONG).show(); Looper.loop(); } }.start(); // 收集裝置引數資訊 collectDeviceInfo(mContext); // 儲存日誌檔案 saveCrashInfo2File(ex); return true; } /** * 收集裝置引數資訊 * * @param context */ public void collectDeviceInfo(Context context) { try { PackageManager pm = context.getPackageManager();// 獲得包管理器 PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);// 得到該應用的資訊,即主Activity if (pi != null) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; info.put("versionName", versionName); info.put("versionCode", versionCode); } } catch (NameNotFoundException e) { e.printStackTrace(); } Field[] fields = Build.class.getDeclaredFields();// 反射機制 for (Field field : fields) { try { field.setAccessible(true); info.put(field.getName(), field.get("").toString()); Log.d(TAG, field.getName() + ":" + field.get("")); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } private String saveCrashInfo2File(Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map.Entry<String, String> entry : info.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\r\n"); } Writer writer = new StringWriter(); PrintWriter pw = new PrintWriter(writer); ex.printStackTrace(pw); Throwable cause = ex.getCause(); // 迴圈著把所有的異常資訊寫入writer中 while (cause != null) { cause.printStackTrace(pw); cause = cause.getCause(); } pw.close();// 記得關閉 String result = writer.toString(); sb.append(result); Log.d("zzz", "錯誤日誌key:" + result); // 儲存檔案 long timetamp = System.currentTimeMillis(); String time = format.format(new Date()); String fileName = "crash-" + time + "-" + timetamp + ".log"; if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { try { File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "crash"); Log.i("CrashHandler", dir.toString()); if (!dir.exists()) dir.mkdir(); FileOutputStream fos = new FileOutputStream(new File(dir, fileName)); fos.write(sb.toString().getBytes()); fos.close(); return fileName; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return null; } }7.2
importandroid.app.Application; public class MainApplication extends Application { @Override public void onCreate() { super.onCreate(); CrashHandler crashHandler = CrashHandler.getInstance(); crashHandler.init(this); } }8、item的佈局檔案
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="300dp" android:layout_weight="1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="秦心" android:textSize="20sp" android:textColor="#D1AA47" android:padding="10dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="已實名認證" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/old" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="26歲" android:textSize="20sp" android:layout_marginLeft="20dp" android:background="#94D3D6" /> <TextView android:id="@+id/job" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="銀行" android:textSize="20sp" android:background="#EFBE42" android:layout_marginLeft="10dp" /> </LinearLayout> <TextView android:id="@+id/desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="90年/天蠍座" android:textSize="18sp" android:layout_marginTop="10sp" android:layout_marginLeft="15dp" /> </LinearLayout>上面就是