已經好久沒有更新博客,今天終於有新的東西可以記錄了。
通過這次的任務學習到了以前沒有注意到的知識點,真的有種書讀百遍,其義自見的感覺。這次又重新認識了《Handler消息機制原理》。這次的任務中有更新UI。但是忘記了在Android4.0以后不能在UI線程訪問網絡,子線程也不能更新UI界面。下面我來展示一下這次的效果圖。



這次的任務是:獲取服務器端的json字符串,並解析顯示在Android界面上。
當我接到這個任務的時候,首先想到的是利用Fragment布局加上ListView布局。但是因為沒有完全掌握,所以失敗了。這是就想到了現在的方案。利用GridView加上ListView來實現。布局是沒有問題。但是寫代碼的時候卻出現了問題。當我獲取到數據並順利解析的時候。卻怎么也傳不到ListView。總是顯示它的size為0.但是通過打印確實獲取到了。這個時候老師讓我利用Handler,便能順利解決問題了。原因就是一開始,我寫到的不能在子線程更新UI。
下面我來粘出我的代碼以供大家參考:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/set_bj"> <GridView android:id="@+id/gv_icons" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numColumns="4" android:layout_alignParentBottom="true"> </GridView> </RelativeLayout>
item_gridview.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <TextView android:id="@+id/tv_icons" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="功能" android:layout_centerInParent="true" android:textSize="13sp" android:textColor="#000000"/> </RelativeLayout>
activity_select.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_id" android:layout_width="0dp" android:layout_weight="2" android:textColor="@android:color/black" android:layout_height="wrap_content" android:textSize="15sp" android:text="題號"/> <TextView android:id="@+id/tv_name" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:textSize="15sp" android:text="題目"/> <TextView android:id="@+id/tv_tech" android:layout_width="0dp" android:layout_weight="7" android:gravity="center" android:layout_height="wrap_content" android:textSize="15sp" android:text="要求"/> </LinearLayout> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp"> </ListView> </LinearLayout>
item_listview.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/tv_id" android:layout_width="0dp" android:layout_weight="1" android:textColor="@android:color/black" android:layout_height="wrap_content" android:gravity="center" android:text="題號"/> <TextView android:id="@+id/tv_name" android:layout_width="0dp" android:layout_weight="3" android:gravity="center" android:layout_height="wrap_content" android:text="題目"/> <TextView android:id="@+id/tv_tech" android:layout_width="0dp" android:layout_weight="6" android:gravity="center" android:layout_height="wrap_content" android:text="要求"/> </LinearLayout>
MainActivity.java
package com.rjxy.student; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.TextView; public class MainActivity extends Activity { private GridView gv_Home; private String[] settingText = {"全部題目","我的選題","個人信息","我的密碼"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gv_Home = (GridView) findViewById(R.id.gv_icons); gv_Home.setAdapter(new MyAdapter()); gv_Home.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { System.out.println(position); switch (position) { case 0: //查看全部題目 Intent intent = new Intent(MainActivity.this,SetlectActivity.class); startActivity(intent); break; case 1: //我的選題 break; case 2: //個人信息 break; case 3: //修改密碼 break; default: break; } } }); } class MyAdapter extends BaseAdapter{ @Override public int getCount() { return settingText.length; } @Override public Object getItem(int position) { return settingText[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = View.inflate(getApplicationContext(), R.layout.item_gridview, null); TextView tv_Home = (TextView) view.findViewById(R.id.tv_icons); tv_Home.setText(settingText[position]); return view; } } }
SetlectActivity.java
package com.rjxy.student; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; public class SetlectActivity extends Activity { private static final int CHANGE_UI = 1; private static final int ERROR = 2; private ListView lv; private List<Data> datas = new ArrayList<Data>(); //主線程創建消息處理器 private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { if (msg.what == CHANGE_UI) { try { JSONArray arr = new JSONArray((String)msg.obj); for (int i = 0; i < arr.length(); i++) { JSONObject temp = (JSONObject) arr.get(i); // Log.d("json", temp.getInt("id")+temp.getString("exp_name")+temp.getString("exp_tech")); Data data = new Data(); data.setId(temp.getInt("id")); data.setExp_name(temp.getString("exp_name")); data.setExp_tech(temp.getString("exp_tech")); //這個地方可以獲取到值但是適配器那位0 datas.add(data); } lv.setAdapter(new MyAdapter()); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select); lv = (ListView) findViewById(R.id.lv); select(); } private void select(){ //子線程更新UI new Thread(){ public void run(){ StringBuilder builder = new StringBuilder(); HttpClient client = new DefaultHttpClient(); String path = "http://10.6.78.254:2016/xampp/graduate/index.php/home/Student/test_android"; HttpGet httpGet = new HttpGet(path); try { HttpResponse response = client.execute(httpGet); StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); if (statusCode == 200) { BufferedReader reader = new BufferedReader (new InputStreamReader(response.getEntity().getContent(),"UTF-8")); for(String s=reader.readLine();s!=null;s=reader.readLine()) { builder.append(s); } String content = builder.toString(); //通知主線程更新UI Message message = new Message(); message.what = CHANGE_UI; message.obj = content; handler.sendMessage(message); }else{ Log.e(MainActivity.class.toString(), "Failed"); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }; }.start(); } class MyAdapter extends BaseAdapter{ @Override public int getCount() { Log.d("AAA", ""+datas.size()); return datas.size(); } @Override public Object getItem(int position) { return datas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = View.inflate(SetlectActivity.this, R.layout.item_listview, null); TextView id = (TextView) view.findViewById(R.id.tv_id); TextView exp_name = (TextView) view.findViewById(R.id.tv_name); TextView exp_tech = (TextView) view.findViewById(R.id.tv_tech); Data data = datas.get(position); Log.d("aaaaa",datas.get(position).getExp_name() ); id.setText(String.valueOf(datas.get(position).getId())); exp_name.setText(datas.get(position).getExp_name()); //Log.i("exp_name", datas.get(position).getExp_name()); exp_tech.setText(datas.get(position).getExp_tech()); return view; } } }
Data.java
package com.rjxy.student; public class Data { private int id; private String exp_name; private String exp_tech; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getExp_name() { return exp_name; } public void setExp_name(String exp_name) { this.exp_name = exp_name; } public String getExp_tech() { return exp_tech; } public void setExp_tech(String exp_tech) { this.exp_tech = exp_tech; } @Override public String toString() { return "Data [id=" + id + ", exp_name=" + exp_name + ", exp_tech=" + exp_tech + "]"; } }
添加權限:
<uses-permission android:name="android.permission.INTERNET"/>
服務器端的代碼:ThinkPHP代碼為:
public function test_android(){ $myModel = new \Think\Model(); $result=$myModel->query("select id,exp_name,exp_tech from g_experiment ;"); echo json_encode($result); }
