从零开始搞懂Android网络请求——异步加载ListView
16lz
2021-01-23
实现思路:
- 自定义AsyncTask类,重写onPreExecute()、doInBackground()、 onPostExecute()三个方法。
- 网络请求数据
- 自定义接受数据的类
- 绑定listview与数据
请求的数据:
{status: 1,data: [{id: 1,name: "如何学好Android——第1章"},{id: 2,name: "如何学好Android——第2章"},{id: 3,name: "如何学好Android——第3章"},{id: 4,name: "如何学好Android——第4章"},{id: 5,name: "如何学好Android——第5章"},{id: 6,name: "如何学好Android——第6章"},{id: 7,name: "如何学好Android——第7章"},{id: 8,name: "如何学好Android——第8章"},{id: 9,name: "如何学好Android——第9章"},{id: 10,name: "如何学好Android——第10章"}],msg: "成功"}
界面效果:
添加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
布局代码:
只需要一个listview就OK。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.zergen.csdnlistview.MainActivity"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"> ListView>LinearLayout>
单个item布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="60dp" android:text="测试测试测试" android:textSize="20sp" android:gravity="center_vertical" android:paddingLeft="5dp" android:id="@+id/classname" />LinearLayout>
实现过程:
代码里面有非常详细的注释
MainActivity:
public class MainActivity extends AppCompatActivity { private ListView listView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listview); new ListViewAsyncTask().execute(); } //自定义AsyncTask类,三个参数,第一个不定量入参,第二个:进度 第三个:结果 public class ListViewAsyncTask extends AsyncTask<Void,Void,String>{ //异步加载执行前所作的,可以用来Loading protected void onPreExecute() { super.onPreExecute(); //Loading } //开启另一个线程,用于后台异步加载的工作 protected String doInBackground(Void... voids) { String result = request("http://139.199.171.179/csdn/api/listviewdata.php"); //返回Json数据 return result; } private String request(String url_data) { try { //网络请求数据 String responsedata = null; URL url = new URL(url_data); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(6000); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream in = conn.getInputStream(); byte[] b = new byte[1024 * 512]; int len; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while((len = in.read(b))>-1){ baos.write(b,0,len); } responsedata = baos.toString(); Log.e("TAG", responsedata); }else { Toast.makeText(getApplicationContext(), "连接网络错误", Toast.LENGTH_SHORT).show(); } return responsedata; } catch (java.io.IOException e) { e.printStackTrace(); } return null; } protected void onPostExecute(String responsedata) { super.onPostExecute(responsedata); //Loading结束,处理数据 //RequstData是用于存储对象信息的自定义类 RequstData requstdata = new RequstData(); //由于数据中有Json数据 所以需要一个ArrayList来存储 List lessondatas = new ArrayList<>(); try { JSONObject obj = new JSONObject(responsedata); requstdata.setStatus(obj.getInt("status")); requstdata.setMsg("msg"); JSONArray jsonarray = obj.getJSONArray("data"); for(int i = 0;inew LesssonData(); JSONObject TempObj = jsonarray.getJSONObject(i); String class_name = TempObj.getString("name"); lessondata.setClassName(class_name); lessondatas.add(lessondata); } //绑定数据 listView.setAdapter(new MyListAdapter(MainActivity.this,lessondatas)); } catch (JSONException e) { e.printStackTrace(); } } }}
RequstData:
public class RequstData { public int status; public String msg; List lesssonDataList =new ArrayList<>(); public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public List getLesssonDataList() { return lesssonDataList; } public void setLesssonDataList(List lesssonDataList) { this.lesssonDataList = lesssonDataList; }}
LessonData:
public class LesssonData { public String ClassName; public String getClassName() { return ClassName; } public void setClassName(String className) { ClassName = className; }}
MyListAdapter :
public class MyListAdapter extends BaseAdapter { List mlesssonDataList; Context mContext; public MyListAdapter(Context context,List lesssonDataList) { this.mlesssonDataList = lesssonDataList; this.mContext = context; } @Override public int getCount() { return mlesssonDataList.size(); } @Override public Object getItem(int i) { return mlesssonDataList.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder viewHolder = new ViewHolder(); if (view==null){ LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view =layoutInflater.inflate(R.layout.item_layout,null); viewHolder.ClassName = (TextView) view.findViewById(R.id.classname); view.setTag(viewHolder); }else { viewHolder = (ViewHolder) view.getTag(); } viewHolder.ClassName.setText(mlesssonDataList.get(i).getClassName()); return view; } public class ViewHolder{ public TextView ClassName; }}
总结:
首先网络请求是一个耗时的操作,所以需要异步加载数据,并且需要对Adpter解析View时使用ViewHolder来优化ListView,防止数据量过大时,会出现卡顿的情况。
更多相关文章
- Android数据存储(一)
- Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行
- Android应用数据存储几种方式(1)
- Android 直接连MySQL数据库
- Android:如何从堆栈中还原ProGuard混淆后的代码
- android recovery 主系统代码分析
- android ndk开发中常用的系统自带网络命令