从后台任务中更新android UI

Posted

技术标签:

【中文标题】从后台任务中更新android UI【英文标题】:Update android UI from do in background task 【发布时间】:2015-07-20 11:23:43 【问题描述】:

我正在使用 AsyncTask 执行后台任务。该任务处于一个while循环中。 如果后台任务仍在运行,如何在执行后更新我的 UI 不起作用。

谢谢

受保护的字符串 doInBackground(Void...params)

        while(true)


        Log.i(LOG_TAG, "Executing Background Task");
        try


            String dataFromBT = btc.getData();
            Log.i(LOG_TAG, "BT Data: "+dataFromBT);
             if(dataFromBT.contains("B1"))
                 dataFromBT = "Warning Message 1";

             
             if(dataFromBT.contains("B2"))
             
                 dataFromBT="Warning Message 2";
             

             if(dataFromBT.contains("B3"))

                 dataFromBT="Warning Message 3";
             

             if(dataFromBT.contains("B4"))

                 dataFromBT="Warning Message 4";
             

            if (groupOwnerAddress!=null) 


                Log.i(LOG_TAG, "Info is not null mobiles connected");



                // This is the server side 
                if (isthisthegrpowner == true) 

                    Log.w(LOG_TAG, "Group Owner: I am the Group Owner ");

                    Log.w(LOG_TAG, "Group Owner: Opening a Server Socket");
                    ServerSocket serverSocket;  
                    serverSocket = new ServerSocket(8988);
                    Log.w(LOG_TAG, "Group Owner: Server Socket Opened, waiting for PEER");

                    Socket client = serverSocket.accept();
                    Log.w(LOG_TAG, "Group Owner: Server Connection Done");
                    serverSocket.setReuseAddress(true); 

                    try

                            // Get client IP from Socket
                            clientipadd = client.getRemoteSocketAddress();
                            clientport = client.getPort();
                            String clientip = clientipadd.toString();
                            Log.w(LOG_TAG, "Group Owner: Client IP from socket found: " + clientip);


                            Log.w(LOG_TAG, "Group Owner: Input Stream Started");
                            InputStream inputstream = client.getInputStream();
                            ByteArrayOutputStream byteArrayOutputStream = 
                                    new ByteArrayOutputStream(1024);
                            byte[] buffer = new byte[1024];

                            String response = "";

                            int bytesRead;
                             while ((bytesRead = inputstream.read(buffer)) != -1)
                                    byteArrayOutputStream.write(buffer, 0, bytesRead);
                                    response += byteArrayOutputStream.toString("UTF-8");
                             


                             // Split the string sent from the client and add it to the HashMap 
                             String input = response;
                             final String[] splitStringArray = input.split(" ");
                             String a = splitStringArray[0];
                             String b = splitStringArray[1];
                             String c = splitStringArray[2];
                             String d = splitStringArray[3];
                             String e = splitStringArray[4];
                             Log.w(LOG_TAG, "Group Owner: Response from client split: "  + " 1: " + a + " 2: "+ b + " 3:" + c + " 4: " + d + " 5: " + e );

                             data.put(clientip, new VehicleInfoEntry(a, b , c));    
                             client.shutdownInput();


                             Log.w(LOG_TAG, "Group Owner: Reply from Peer: " + response);

                    finally

                        Log.w(LOG_TAG, "Group Owner: Output Stream started");
                        OutputStream stream = client.getOutputStream();
                        PrintStream printStream = new PrintStream(stream); 
                        printStream.print("hello hellomac hellodata" + Latitude + "  " + Longitude + dataFromBT);
                        Log.w(LOG_TAG, "Group Owner: Output Stream finished");

                        serverSocket.close();
                        Log.w(LOG_TAG, "Group Owner: Socket Closed");
                    

                    // This is the client side
                     else

                    Log.w(LOG_TAG, "PEER: I am a PEER");
                    InetAddress ownerAdd = groupOwnerAddress;
                    int ownerPort = 8988;
                    Socket server = new Socket(); 
                    try 


                        server.connect((new InetSocketAddress(ownerAdd, ownerPort)));
                        Log.w(LOG_TAG, "PEER: Socket done ");

                        Log.w(LOG_TAG, "PEER: Output Stream Started ");
                        OutputStream stream = server.getOutputStream();
                        PrintStream printStream = new PrintStream(stream); 
                        printStream.print("hello hellomac hellodata" + " " + Latitude + " " + Longitude + dataFromBT);

                        Log.w(LOG_TAG, "PEER: Output Stream Done");

                        server.shutdownOutput();
                       // printStream.close();
                     finally 

                        Log.w(LOG_TAG, "PEER: Input Stream Started");

                        InputStream inputstream = server.getInputStream();
                        ByteArrayOutputStream byteArrayOutputStream = 
                                new ByteArrayOutputStream(1024);
                        byte[] buffer = new byte[1024];

                        String response = "";

                        int bytesRead;
                         while ((bytesRead = inputstream.read(buffer)) != -1)
                                byteArrayOutputStream.write(buffer, 0, bytesRead);
                                response += byteArrayOutputStream.toString("UTF-8");

                                Log.w(LOG_TAG, "PEER: Reply from Group Owner:  " + response);

                                server.close();
                                Log.w(LOG_TAG, "PEER: Server socket closed");

                         

                    

                    
                

                 catch (IOException e1) 
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                finally 


                try 

                    Thread.sleep(2000); // changed to 5000 for other peer
                 catch (InterruptedException e) 
                    e.printStackTrace();
                 





            



    

【问题讨论】:

使用 BroadcastReceiver 跟随链接:***.com/questions/14695537/… 【参考方案1】:

如果您想从后台线程使用 UI,请使用 runOnUiThread,如下所示 doInBackground

runOnUiThread(new Runnable()
        public void run() 
            // update UI
        

【讨论】:

您好,感谢您的帮助!我一直在尝试这样做,但我没有让它工作....我应该将 runOnUiThread 放在 doInBackground 中吗? 是的,我在回答中提到了你必须在 doInbackground 中使用它【参考方案2】:

使用publishProgress 方法。您在onProgressUpdate 中所做的任何事情都在 UI 线程上运行

 private class TestAsyncTask extends AsyncTask<Void, String, Void> 
        @Override
        protected Void doInBackground(Void... voids) 
            SystemClock.sleep(1000);
            publishProgress("Test");
            SystemClock.sleep(1000);
            return null;
        

        @Override
        protected void onProgressUpdate(String... values) 
            String test = values[0];
            // Do something with it
        
    

protected void onProgressUpdate(进度...值)

添加在 API 级别 3 之后在 UI 线程上运行 调用 publishProgress(Progress...)。指定的值是 传递给 publishProgress(Progress...) 的值。

参数 values 表示进度的值。

【讨论】:

以上是关于从后台任务中更新android UI的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android开发中用AsyncTask异步更新UI界面

java 可以使用v7.1 UI.access()方法执行后台任务以在Vaadin中执行后台工作和安全UI更新。目前

Android中使用IntentService运行后台任务

Android中使用IntentService运行后台任务

将后台线程的结果传达给 Android 中的 Ui 线程的正确方法

Android中UI线程与后台线程交互设计的6种方法