1

我有这行代码完全没有问题,唯一的问题是每次执行此代码时,应用程序都会等待所有进程完成,使界面可能有半秒钟没有响应。我找到的最佳解决方案是使用 a Thread,但它会导致一些问题,所以我求助于AsyncTask我无法理解的方法。谁能帮助我如何将它实现到这行代码?

            ima.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    search.clearFocus();
                    currentItem = ssil;
                    if (currentRoom.equals("None")) {
                        Toast.makeText(StartMoving.this, "Please select a room before adding an item", Toast.LENGTH_LONG).show();
                    }else{

                        try {
                            String currentitemholder = startmoving.getSingleItemName(currentMove, currentRoom, currentItem);
                            if (currentitemholder.equals(currentItem)) {
                                String ssi = startmoving.getSingleItemValue(currentMove, currentRoom, currentItem);
                                String ssiw = startmoving.getSingleItemWeight(currentMove, currentRoom, currentItem);
                                String stw = startmoving.getTotalWeight(currentMove);
                                String srw = startmoving.getRoomWeight(currentMove, currentRoom);
                                String diw = startmoving.getListItemWeight(currentItem);
                                int istw = Integer.parseInt(stw);
                                int isiw = Integer.parseInt(ssiw);
                                int isi = Integer.parseInt(ssi);
                                int isrw = Integer.parseInt(srw);
                                int idiw = Integer.parseInt(diw);
                                currentItemValue = "" + ++isi;
                                currentItemWeight = "" + (isiw + idiw);
                                currentTotalItemWeight = "" + (istw + idiw);
                                currentRoomWeight = "" + (isrw + idiw);
                                currentTotalItem = startmoving.getTotalItem(currentMove) + 1; 
                                startmoving.updateItems(currentMove, currentRoom, currentItem, currentItemValue, currentItemWeight);
                                startmoving.setMoveWeight(currentTotalItemWeight, currentMove);
                                startmoving.setRoomWeight(currentRoomWeight, currentMove, currentRoom); 
                                startmoving.setTotalItem(currentMove, currentTotalItem);
                                String displayname = startmoving.getItemName(currentMove, currentRoom);
                                String displayvalue = startmoving.getItemValue(currentMove, currentRoom);
                                String displayweight = startmoving.getItemWeightLBS(currentMove, currentRoom);
                                String displaytotalweight = startmoving.getTotalWeightLBS(currentMove);
                                String displayroomweight = startmoving.getRoomWeightLBS(currentMove, currentRoom);
                                roomContent.setText(displayname);
                                itemValue.setText(displayvalue);
                                itemWeight.setText(displayweight);
                                totalweight.setText(displaytotalweight);
                                roomweight.setText(displayroomweight); 
                                int displaytotalitem = startmoving.getTotalItem(currentMove); 
                                totalitem.setText("" + displaytotalitem);
                            }
                        }catch (Exception e) {
                            // TODO Auto-generated catch block
                            currentItemValue = "1";
                            currentItemWeight = ssiw;
                            String stw = startmoving.getTotalWeight(currentMove);
                            String srw = startmoving.getRoomWeight(currentMove, currentRoom);
                            String diw = startmoving.getListItemWeight(currentItem);
                            int istw = Integer.parseInt(stw);
                            int isrw = Integer.parseInt(srw);
                            int idiw = Integer.parseInt(diw);
                            currentTotalItemWeight = "" + (istw + idiw);
                            currentRoomWeight = "" + (isrw + idiw);
                            currentTotalItem = startmoving.getTotalItem(currentMove) + 1; 
                            startmoving.addNewItems(currentMove, currentRoom, currentItem, currentItemValue, currentItemWeight);
                            startmoving.setMoveWeight(currentTotalItemWeight, currentMove);
                            startmoving.setRoomWeight(currentRoomWeight, currentMove, currentRoom); 
                            startmoving.setTotalItem(currentMove, currentTotalItem);
                            startmoving.setTotalItem(currentMove, currentTotalItem);
                            String displayname = startmoving.getItemName(currentMove, currentRoom);
                            String displayvalue = startmoving.getItemValue(currentMove, currentRoom);
                            String displayweight = startmoving.getItemWeightLBS(currentMove, currentRoom);
                            String displaytotalweight = startmoving.getTotalWeightLBS(currentMove);
                            String displayroomweight = startmoving.getRoomWeightLBS(currentMove, currentRoom);
                            roomContent.setText(displayname);
                            itemValue.setText(displayvalue);
                            itemWeight.setText(displayweight);
                            totalweight.setText(displaytotalweight);
                            roomweight.setText(displayroomweight); 
                            int displaytotalitem = startmoving.getTotalItem(currentMove); 
                            totalitem.setText("" + displaytotalitem);
                        }
                    }
                }
            });

            imr.setOnClickListener(new OnClickListener() {

                @SuppressLint("ShowToast")
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    search.clearFocus();
                    currentItem = ssil;
                    if (currentRoom.equals("None")) {
                        Toast.makeText(StartMoving.this, "Please select a room before removing an item", Toast.LENGTH_LONG).show();
                    }else{

                        try {
                            String currentitemholder = startmoving.getSingleItemName(currentMove, currentRoom, currentItem);
                            if (currentitemholder.equals(currentItem)) {
                                String ssi = startmoving.getSingleItemValue(currentMove, currentRoom, currentItem);
                                String ssiw = startmoving.getSingleItemWeight(currentMove, currentRoom, currentItem);
                                String stw = startmoving.getTotalWeight(currentMove);
                                String srw = startmoving.getRoomWeight(currentMove, currentRoom);
                                String diw = startmoving.getListItemWeight(currentItem);
                                int istw = Integer.parseInt(stw);
                                int isiw = Integer.parseInt(ssiw);
                                int isi = Integer.parseInt(ssi);
                                int isrw = Integer.parseInt(srw);
                                int idiw = Integer.parseInt(diw);
                                if (isi > 1) {
                                    currentItemValue = "" + --isi;
                                    currentItemWeight = "" + (isiw - idiw);
                                    currentTotalItemWeight = "" + (istw - idiw);
                                    currentRoomWeight = "" + (isrw - idiw);
                                    currentTotalItem = startmoving.getTotalItem(currentMove) - 1; 
                                    startmoving.updateItems(currentMove, currentRoom, currentItem, currentItemValue, currentItemWeight);
                                    startmoving.setMoveWeight(currentTotalItemWeight, currentMove);
                                    startmoving.setRoomWeight(currentRoomWeight, currentMove, currentRoom); 
                                    startmoving.setTotalItem(currentMove, currentTotalItem);
                                    startmoving.setTotalItem(currentMove, currentTotalItem);
                                    String displayname = startmoving.getItemName(currentMove, currentRoom);
                                    String displayvalue = startmoving.getItemValue(currentMove, currentRoom);
                                    String displayweight = startmoving.getItemWeightLBS(currentMove, currentRoom);
                                    String displaytotalweight = startmoving.getTotalWeightLBS(currentMove);
                                    String displayroomweight = startmoving.getRoomWeightLBS(currentMove, currentRoom);
                                    roomContent.setText(displayname);
                                    itemValue.setText(displayvalue);
                                    itemWeight.setText(displayweight);
                                    totalweight.setText(displaytotalweight);
                                    roomweight.setText(displayroomweight); 
                                    int displaytotalitem = startmoving.getTotalItem(currentMove); totalitem.setText("" + displaytotalitem);
                                }else{
                                    String sstw = startmoving.getTotalWeight(currentMove);
                                    String ssrw = startmoving.getRoomWeight(currentMove, currentRoom);
                                    int isstw = Integer.parseInt(sstw);
                                    int issrw = Integer.parseInt(ssrw);
                                    currentTotalItemWeight = "" + (isstw - idiw);
                                    currentRoomWeight = "" + (issrw - idiw);
                                    currentTotalItem = startmoving.getTotalItem(currentMove) - 1; startmoving.setMoveWeight(currentTotalItemWeight, currentMove);
                                    startmoving.setRoomWeight(currentRoomWeight, currentMove, currentRoom);
                                    startmoving.deleteItem(currentMove, currentRoom, currentItem); startmoving.setTotalItem(currentMove, currentTotalItem);
                                    startmoving.setTotalItem(currentMove, currentTotalItem);
                                    String displayname = startmoving.getItemName(currentMove, currentRoom);
                                    String displayvalue = startmoving.getItemValue(currentMove, currentRoom);
                                    String displayweight = startmoving.getItemWeightLBS(currentMove, currentRoom);
                                    String displaytotalweight = startmoving.getTotalWeightLBS(currentMove);
                                    String displayroomweight = startmoving.getRoomWeightLBS(currentMove, currentRoom);
                                    roomContent.setText(displayname);
                                    itemValue.setText(displayvalue);
                                    itemWeight.setText(displayweight);
                                    totalweight.setText(displaytotalweight);
                                    roomweight.setText(displayroomweight); 
                                    int displaytotalitem = startmoving.getTotalItem(currentMove); 
                                    totalitem.setText("" + displaytotalitem);
                                }   
                            }
                        }catch (Exception e) {
                            // TODO Auto-generated catch block

                        }
                    }
                }
            });

如您所见,这是两个按钮,它们调用数据库(发送和接收数据)并将其显示到 GUI。

编辑

感谢您的精彩回复!在决定正确答案之前,我会先研究 AsyncTask。仍然需要处理你给我的所有这些信息。

编辑 忘了提到 startmoving 是我的数据库模块

4

4 回答 4

2

如果您执行长时间的操作,例如加载文件或访问数据,您的 Android 应用程序的用户界面将阻塞,直到相应的代码完成。

异步任务

为了使用 AsyncTask 类,您必须扩展它并至少覆盖 doInBackground() 方法。

您需要实现的最常见方法是:

   1. onPreExecute() – called on the UI thread before the thread starts running. This method is usually used to setup the task, for example by displaying a progress bar.

   2. doInBackground(Params…) – this is the method that runs on the background thread. In this method you should put all the code you want the application to perform in background. Referring to our Simple RSS Aplication, you would put here the code that downloads the XML feed and does the parsing. The doInBackground() is called immediately after onPreExecute(). When it finishes, it sends the result to the onPostExecute().

   3. onProgressUpdate() - called when you invoke publishProgress() in the doInBackground().

   4. onPostExecute(Result) – called on the UI thread after the background thread finishes. It takes as parameter the result received from doInBackground().

现在在您的代码选择中,您可以做什么。

所有数据库操作和数据操作代码都写在doInBackground(Params…)方法中,并在方法中显示数据onPostExecute(Result)

谢谢。

于 2012-10-24T04:32:13.853 回答
1

AsyncTask在另一个线程内执行所有内容,该doInBackground()线程无权访问您的视图所在的 GUI。

preExecute()postExecute()在此新线程中发生繁重工作之前和之后为您提供对 GUI 的访问,您甚至可以将长时间操作的结果传递postExecute()给然后显示任何处理结果。

Android 通过一个线程修改用户界面,即所谓的 UI 线程。如果您直接在 UI 线程上执行长时间运行的操作,例如从 Internet 下载文件,您的应用程序的用户界面将“冻结”,直到相应的任务完成。发生这种情况时,用户很容易认为您的应用程序很慢。

AsyncTask 允许正确和轻松地使用 UI 线程。此类允许在 UI 线程上执行后台操作并发布结果,而无需操作线程和/或处理程序。

  1. onPreExecute()– 在线程开始运行之前在 UI 线程上调用。此方法通常用于设置任务,例如通过显示进度条。

  2. doInBackground(Params…)– 这是在后台线程上运行的方法。在这种方法中,您应该将您希望应用程序在后台执行的所有代码。参考我们的简单 RSS 应用程序,您可以将下载 XML 提要并进行解析的代码放在这里。在 onPreExecute() 之后立即调用 doInBackground()。完成后,它将结果发送到 onPostExecute()。

  3. onProgressUpdate()- 在 doInBackground() 中调用 publishProgress() 时调用。

  4. onPostExecute(Result)– 在后台线程完成后在 UI 线程上调用。它将从 doInBackground() 接收到的结果作为参数。

AsyncTask 是一个泛型类,它使用 3 种类型: AsyncTask。

Params – the input. what you pass to the AsyncTask
Progress – if you have any updates, passed to onProgressUpdate()
Result – the output. what returns doInBackground()

创建任务后,可以像这样执行它:

new DownloadTast().execute(url1, url2, urln);

这是 AsyncTask 的一个示例

于 2012-10-24T04:39:33.553 回答
1

好的,在不给你解决方案的情况下,我认为最好开始阅读 Android 中的异步请求:http: //developer.android.com/reference/android/os/AsyncTask.html。了解 Web 的异步特性将帮助您了解 UI 与其可能呈现的数据的分离。

响应性是将 UI 与数据分开的第一大原因。对于使用 EDT(事件分配线程)的 Java Swing 开发人员来说,这可能是最好的解释:http: //docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html。有很多缓慢的应用程序示例,开发人员会将长时间运行的进程附加到他们的按钮或其他东西上,然后尝试通过使用自己的线程来加快处理速度来修复它。Swing 最终在 Java 6 中使用 SwingWorker 和 doInBackground() 解决了这个问题。对于转向 Android 的 Swing 开发人员,他们可能会查看 AsyncTask 并问,为什么它在 Java 中没有那么简单?

因此,花点时间熟悉 AsyncTask,了解如何使用它,如何将它与 Listeners 结合以获得更大的灵活性,然后您将了解如何更改代码。

让我们知道您是否需要更多帮助以指明正确的方向。

于 2012-10-24T04:42:11.403 回答
1

基本上,您需要扩展 AsyncTask 类并进行自己的实现。您利用了 doInBackground() 函数在非 UI 线程中运行的事实,并且它返回的结果可以在 UI 线程中运行的 onPostExecute() 函数中使用。

你提到你的代码调用了一个数据库,所以我假设你的“startmoving”对象是数据库模块。对于下面的示例代码,我将仅将其称为 MovingDb 类,因为它没有在您的代码中显示实际的类名是什么。

// this will hold all your calculated value
private class DisplayInfo {
   String displayName, displayValue, displayWeight, displayTotalWeight, displayRoomWeight;
   int displayTotalItem;
}

private class ItemHolderTask extends AsyncTask<MovingDb, Integer, DisplayInfo> {

   protected DisplayInfo doInBackground(MovingDb... movingDbs) {
      // this code runs in background thread so do your DB work here
      if (movingDbs != null && movingDbs.length > 0 && movingDbs[0] != null) {
         MovingDb startMoving = movingDbs[0];
         // move all your db operations here
         String currentItemHolder = startMoving.getSingleIteName(....)
         // blah blah
         DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.displayName = startMoving.getItemName(...);
         displayInfo.displayValue = startMoving.getItemValue(...);
         // set up the rest of your display info values
         return displayInfo;
      }
   }

   protected void onPostExecute(DisplayInfo displayInfo) {
      // the displayInfo you return from doInBackground comes here
      if (displayInfo != null) {
         roomContent.setText(displayInfo.displayName);
         itemValue.setText(displayInfo.displayValue);
         // and so on...
      }
   }
}

在您的 onClick 函数中,您只需启动 ItemHolderTask:

new ItemHolderTask().execute(startMoving);
于 2012-10-24T04:48:40.123 回答