已经好久没有更新博客,今天终于有新的东西可以记录了。
通过这次的任务学习到了以前没有注意到的知识点,真的有种书读百遍,其义自见的感觉。这次又重新认识了《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 ThinkModel(); $result=$myModel->query("select id,exp_name,exp_tech from g_experiment ;"); echo json_encode($result); }