首页 > 代码库 > Servlet回传的数据显示在界面上

Servlet回传的数据显示在界面上

上一篇的文章中,我给出了android和servlet之间数据的传递。实现了:android端数据打包--》发送给servlet端解析--》返回给android端

但还有一个很重要的内容,我以为很简单可以实现。结果纠结了两天才实现。即上述步骤的最后一步,就是【返回的数据显示到android上】

这个过程其实挺简单的,修改上一篇博文中2.1中的代码如下就可以了

public String sendJson(){        StringBuilder result = new StringBuilder();        String urlStr = "http://192.168.1.24:8080/servletTest/test";        HttpPost post = new HttpPost(urlStr);                try{            JSONObject json = new JSONObject();            json.put("book_id", id);            System.out.println("=============="+json.toString());                        StringEntity se = new StringEntity(json.toString());            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));            post.setEntity(se);                        HttpClient httpClient = getHttpClient();            HttpResponse httpResponse = httpClient.execute(post);            /////////////////////////////            int httpCode = httpResponse.getStatusLine().getStatusCode();            if(httpCode==HttpURLConnection.HTTP_OK && httpResponse != null){                HttpEntity entity = httpResponse.getEntity();                InputStream inputStream = entity.getContent();                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);                BufferedReader reader = new BufferedReader(inputStreamReader);                String s;                while((s=reader.readLine()) != null){                    result.append(s);                }                reader.close();                                JSONObject object =  new JSONObject(result.toString());                String str = object.getString("book_list");                //detail1.setBookText(str);                return str;            }            ////////////////////////////        }catch(Exception exception){            exception.printStackTrace();        }        return null;    }

红色区域内的内容是新添加的,将返回的httpResponse中的内容提取出来,并返回一个str字符串。

到目前为止,都没有什么问题。但是当我们试图将返回的str字符串用于更新UI内容的时候,android报错,说UI内容的修改只能在创建UI的线程中才能修改,也就是说只能在主线程中修改;而不能在子线程中修改。

这个时候就出现了一个矛盾体。访问服务器的操作必须要在子线程中,因为它是一个耗时操作,会降低UI线程的性能;而UI的更新操作必须在UI线程中,子线程不允许修改UI。这个时候,我们需要的就是——线程间的通讯。

是的,当子线程获取了servlet返回的数据后,将数据通过线程间通讯的方式发送给主线程。主线程收到这个消息后,再更新UI。就是这样一个过程。

这个时候就不再涉及到servlet端的代码了,因为servlet已经把数据都返回回来。所以下面我只给出android端的代码。

/****  android code  ****/

package com.example.douban250;@SuppressLint("HandlerLeak") public class BookDetailsActivity extends ActionBarActivity{    private BookDetail detail1;    private ImageButton backButton;    private String responseMsg = "";    int id;    private Handler mMainHandler, mChildHandler;            protected void onCreate(Bundle savedInstanceState){        super.onCreate(savedInstanceState);        this.requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.book_detail_main);                detail1 = (BookDetail)this.findViewById(R.id.book_detail);                Intent intent = getIntent();        id = intent.getIntExtra("id", -1);        mMainHandler = new Handler(){            public void handleMessage(Message msg){                //接收子线程的消息                detail1.setBookText((String)msg.obj);                System.out.println("==========main thread get the message:"+msg.obj);                System.out.println("Finally, the message is :"+msg.obj);                            }        };        QueryThread thread = new QueryThread();        thread.start();                while(mChildHandler == null){                    }        if(mChildHandler != null){            //发送消息给子线程            Message childMsg = mChildHandler.obtainMessage();            childMsg.obj = mMainHandler.getLooper().getThread().getName();            System.out.println("==========send message to mChild: "+childMsg.obj);            mChildHandler.sendMessage(childMsg);        }            }        public void onDestroy(){        super.onDestroy();        mChildHandler.getLooper().quit();    }        public String getBookDetails(){                //与servlet交互的实现代码        StringBuilder result = new StringBuilder();        String urlStr = "http://192.168.1.21:8080/servletTest/test";        HttpPost post = new HttpPost(urlStr);                try{            //发送request            JSONObject json = new JSONObject();            json.put("book_id", id);            System.out.println("=============="+json.toString());                        StringEntity se = new StringEntity(json.toString());            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));            post.setEntity(se);                        HttpClient httpClient = getHttpClient();            HttpResponse httpResponse = httpClient.execute(post);            //接收到response并处理            int httpCode = httpResponse.getStatusLine().getStatusCode();            if(httpCode==HttpURLConnection.HTTP_OK && httpResponse != null){                HttpEntity entity = httpResponse.getEntity();                InputStream inputStream = entity.getContent();                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);                BufferedReader reader = new BufferedReader(inputStreamReader);                String s;                while((s=reader.readLine()) != null){                    result.append(s);                }                reader.close();                                JSONObject object =  new JSONObject(result.toString());                String str = object.getString("book_list");                //detail1.setBookText(str);                //得到最终返回的结果                return str;            }                    }catch(Exception exception){            exception.printStackTrace();        }        return null;    }        public HttpClient getHttpClient(){        BasicHttpParams httpParams = new BasicHttpParams();        HttpConnectionParams.setConnectionTimeout(httpParams, 5*1000);        HttpConnectionParams.setSoTimeout(httpParams, 10*1000);        HttpClient client = new DefaultHttpClient(httpParams);        return client;    }        class QueryThread extends Thread{        public void run(){                        //初始化消息循环队列,需要在Handler创建之前            Looper.prepare();            mChildHandler = new Handler(){                public void handleMessage(Message msg){                    //访问网络等工作                    String book_titleString = getBookDetails();                    System.out.println("================book_title from servlet is "+book_titleString);                    Message toMain = mMainHandler.obtainMessage();                    toMain.obj = book_titleString;                    //向主线程当前线程的Looper对发送message                    System.out.println("================send message to main thread: "+book_titleString);                    mMainHandler.sendMessage(toMain);                }            };            //启动子线程消息循环队列            Looper.loop();            System.out.println("================json is done!");        }    }}

过程就是这样的,onCreate方法中的以下这段代码,我也不是太懂是什么意思。但是我理解的就是讲mChildHandler注册到消息队列中去。这样的话mMainHandler就知道有这么一个消息了。

if(mChildHandler != null){            //发送消息给子线程            Message childMsg = mChildHandler.obtainMessage();            childMsg.obj = mMainHandler.getLooper().getThread().getName();            System.out.println("==========send message to mChild: "+childMsg.obj);            mChildHandler.sendMessage(childMsg);        }

然后QueryThread中的下面这段代码就是,就是将网络访问中的返回值——book_titleString当做消息的内容,传递给mMainHandler。

mChildHandler = new Handler(){                public void handleMessage(Message msg){                    //访问网络等工作                    String book_titleString = getBookDetails();                    System.out.println("================book_title from servlet is "+book_titleString);                    Message toMain = mMainHandler.obtainMessage();                    toMain.obj = book_titleString;                    //向主线程当前线程的Looper对发送message                    System.out.println("================send message to main thread: "+book_titleString);                    mMainHandler.sendMessage(toMain);                }            };

最后mMainHandler作为主线程,接收到这个消息,并将其中的信息提取出来,更新UI。下面标红的代码就是我封装的一个修改UI的代码。跟textView.setText((String)msg.obj)是一个意思。

mMainHandler = new Handler(){            public void handleMessage(Message msg){                //接收子线程的消息                detail1.setBookText((String)msg.obj);                System.out.println("==========main thread get the message:"+msg.obj);                System.out.println("Finally, the message is :"+msg.obj);                            }        };

 

 

 

 

 

 

 

 

 

 

Bon Appetite~

Servlet回传的数据显示在界面上