【问题标题】:Need help in showing the POPup dialog in the UI while data loads in background async task在后台异步任务中加载数据时需要帮助在 UI 中显示弹出对话框
【发布时间】:2025-11-24 09:10:01
【问题描述】:

我在异步任务的 onPreExecute 方法中有一个进度对话框,但在异步任务从数据库中获取数据时它不会立即显示。您能否建议在单击按钮时立即显示进度对话框的内容。在当前场景中,屏幕在获取数据时会冻结。获取后,它会移动到下一个屏幕,但同时它不会显示我的进度对话框。 下面是异步任务

public class waitAsync extends AsyncTask<String, Void, String> {
    ResultSet rs=null;
   private ProgressDialog processingDialog;
    static Connection conn=null;
    Statement stmt;
   // waitThread wt= new waitThread();
    @Override
    protected void onPreExecute() {
      //  ProgressDialog processingDialog;
        super.onPreExecute();
        processingDialog = new ProgressDialog(MainActivity.mCon);
        processingDialog.show();
        processingDialog.setContentView(R.layout.activity_wait);
        //processingDialog.setMessage("Loading...");

    }
    @Override
   protected String doInBackground(String... params) {
        try {


            String driver = "net.sourceforge.jtds.jdbc.Driver";
            String ip = "mfb.dfsdfsdf.ap-north-1.rds.amazonaws.com";
            String classs = "net.sourceforge.jtds.jdbc.Driver";
            String db = "MyDatabase";
            String un = "xxxwww";
            String password = "xxxxxx";
            Class.forName(classs);

            String ConnURL = null;
            ConnURL = "jdbc:jtds:sqlserver://" + ip + ";"
                    + "databaseName=" + db + ";user=" + un + ";password="
                    + password + ";";
            conn = DriverManager.getConnection(ConnURL);

            stmt = conn.createStatement(
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);
            rs=stmt.executeQuery(params[0]);
            int size = 0;


            //conn.close();
            MainActivity.getdata=rs;
            MainActivity.flag=1;
            //Thread.sleep(5000);
        } catch (Exception e)
        {
            Log.w("Error connection", "" + e.getMessage());
        }
        return null;
        }
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        processingDialog.dismiss();
      //  wt.interrupted();


    }



}

从 Main_Activity 调用异步任务

Getdata(String bookid)
{
  String SQL="Select eb.book_name,eb.AuthorID,ma.Name,eb.GenreID_M,eb.GenreID_D,gm.Genre_MN+'- '+gd.Genre_DN as Genre,isnull(eb.pubDate,'') pubDate,isnull(eb.book_Loc,'') book_Loc,\n" +
                    " eb.Price,eb.ico_Loc,eb.Descrip from Master_ebook eb inner join Master_Author ma on eb.AuthorID=ma.Author_ID\n" +
                    " inner join Master_Genre_M gm on eb.GenreID_M=gm.Genre_MID\n" +
                    "inner join Master_Genre_D gd on eb.GenreID_D= gd.Genre_DID where eb.bookID=" + bookid;


            new waitAsync().execute(SQL);

            int c=0;
            while(MainActivity.flag==0)
            {
                c++;
            }

            if(MainActivity.flag==1)
            {
                MainActivity.flag=0;
                //processingDialog.dismiss();
            }

            ResultSet rs=MainActivity.getdata;
}

【问题讨论】:

  • 因为显然你已经用while(MainActivity.flag==0) { c++; } 阻塞了 UI 线程 .... 此代码使 AsyncTask 无用
  • 我还能做什么?你能建议吗?我将不得不等到我的异步任务获取我的数据,因为我将在主要活动 getdata 方法中立即需要该数据
  • 我认为我在您的 asynctask 中所做的更改就足够了
  • 我试过了,它没有任何影响。 @Maharith

标签: java android multithreading android-asynctask


【解决方案1】:

通过 asynctask 中的构造函数将活动上下文传递给异步任务,并改用该上下文。喜欢

     Context mainActivityCtxt;  
     waitAsync(Context ctx) {
         this.mainActivityCtxt = ctx;
     };  

     new waitAsync(mainActivityCtxt).execute(SQL); 

希望这会有所帮助。

【讨论】:

  • 嗨,我之前试过,它给出了一个异常错误“android.util.AndroidRuntimeException:在添加内容之前必须调用 requestFeature()”。后来我意识到我必须写 processingDialog.show();在 setContentView 之前。
  • 然后尝试使用 setMessage("some message") 而不是 setcontentview 并检查至少显示对话框。此外,通过构造函数传递上下文,而不是通过静态引用使用。
  • 在显示进度对话框之前不能设置setContentView(R.layout.activity_wait);
【解决方案2】:

在异步任务之后你不需要这样的循环。它会阻塞你的 UI 线程。

while(MainActivity.flag==0) // wrong - blocking main thread
            {
                c++;
            }

您需要在活动中创建一个方法,例如onDataAvailable 并在此方法中 你可以做任何你想做的事情,要么去下一个活动,要么去别的什么,然后从onPostExecute调用这个方法

  @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        processingDialog.dismiss();
      //  call load complete method here


    }

这是您更新的异步任务。

public class WaitAsyncTask extends AsyncTask<String, Void, String> {

    private WeakReference<MainActivity> activityRef;

    public WaitAsyncTask(MainActivity activity){
        activityRef = new WeakReference<MainActivity>(activity);
    }

     @Override
     protected void onPreExecute() {
        super.onPreExecute();
        // show dialog
    }
    @Override
    protected String doInBackground(String... params) {
        // do you work in background
        return null;
    }

    @Override
    protected void onPostExecute(String data) {
        super.onPostExecute(data);
        // hide dialog
        if(activityRef.get() != null){
            // call load completed method in activity
            activityRef.get().loadCompleted(data);
        }
    }
} // WaitAsyncTask

在您的MainActivity 中,创建一个您希望接收结果的方法。我已经创建了这个方法

  public void loadCompleted(String data){
        // this will be called automatically after fetching data is completed
    }

MainActivity 我从我的任务中调用。您不需要 while 循环来等待。获取数据后会调用此方法。

【讨论】:

  • 终于成功了。非常感谢我的朋友@mallaudin
  • 很高兴知道这一点。干杯