zoukankan      html  css  js  c++  java
  • 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~

  • 相关阅读:
    GD32E507移植FreeRTOS
    FreeRTOS学习笔记——任务基础知识
    FreeRTOS学习笔记——系统配置
    am335x WG209 wifi模块自动配置的脚本
    树莓派学习笔记——Systemd进程启动
    am335x WG209 wifi模块驱动移植
    树莓派学习笔记——搭建Samba服务端
    树莓派学习笔记——内核编译
    一个复制文件的Shell脚本
    Makefile学习笔记——Makefile通配符的使用
  • 原文地址:https://www.cnblogs.com/zhawj159753/p/3958368.html
Copyright © 2011-2022 走看看