从 DialogFragment 调用的 AsyncTask 中的 ProgressDialog 未显示

Posted

技术标签:

【中文标题】从 DialogFragment 调用的 AsyncTask 中的 ProgressDialog 未显示【英文标题】:ProgressDialog in AsyncTask called from DialogFragment is not shown 【发布时间】:2014-10-11 22:02:49 【问题描述】:

我正在从 DialogFragment 内部执行 AsyncTask,但在 doInBackground 期间未显示进度条。代码如下:

public class GetCustomerSoapAsync extends AsyncTask<Void, Void, String>

  ProgressDialog prg;
  ActionBarActivity activity;
  GetResponseFromGetCustomer listener;


  public GetCustomerSoapAsync(ActionBarActivity activity, GetResponseFromGetCustomer listener)
  
    this.activity = activity;
    this.listener = listener;
    prg = new ProgressDialog(activity);
    prg.setMessage("Lütfen Bekleyin");
    Log.i("ED","Progress will be shown");
    prg.show();

  



  @Override protected String doInBackground(Void... params)
  
    //some stuff
  

  @Override protected void onPostExecute(String s)
  
    listener.getResponseFromGetCustomer(s);

    if (prg.isShowing())
    
        prg.dismiss();
    

 

我称之为:

public class B1_PhoneNumberFragment extends android.support.v4.app.Fragment

 ...
  buttonLogin.setOnClickListener(new OnClickListener()
    

        @Override
        public void onClick(View v)
        
          ...


          PhoneNumberVerified dialog = new PhoneNumberVerified();
                dialog.show(getFragmentManager(), "NumberVerifiedByUser");

        
        ...
    
   ....



  public class PhoneNumberVerified extends DialogFragment
  

   @Override
   public Dialog onCreateDialog(Bundle savedInstanceState)
   
     // Use the Builder class for convenient dialog construction
     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
     // Format of this dialog will be changed
     builder.setMessage("Numaranız doğru mu?\n" + "0" + number)
                .setPositiveButton(R.string.yes,
                        new DialogInterface.OnClickListener()
                        
                            public void onClick(DialogInterface dialog,
                                                int id)
                            
                                GlobalApplication.getUser().setPhone(
                                        (excludeParanthesis
                                                (number)));

                                //AsyncTask is not working properly,
                                // progress dialog is not shown and code flows before
                                // response is set to s
                                GetCustomerSoapAsync getCustomerSoapAsync =
                                        new GetCustomerSoapAsync(
                                                (ActionBarActivity) getActivity(),
                                                new GetResponseFromGetCustomer()

                                                
                                                    @Override
                                                    public void getResponseFromGetCustomer
                                                            (String s)
                                                    
                                                        response = s;
                                                    
                                                );

                                getCustomerSoapAsync.execute();


                                Log.i("ED", "Response after GetCustomerSoapAsync callback: " +
                                            response);


最后,可能是由于任务流程有缺陷或其他原因,回调无法完成其工作,并且响应未设置为 AsyncTask 的返回值。

感谢您的帮助!

【问题讨论】:

activity.runOnUiThread(new Runnable() public void run() //pgd ); 【参考方案1】:

你应该使用onPreExecute

class Task1 extends AsyncTask<Object, Void, String []> 

    /** The Progress dialog. */
    private final ProgressDialog dialog = new ProgressDialog(YourActivity.this);


    /**
     * Set the Progress dialog.
     */
    protected void onPreExecute() 
    
    super.onPreExecute();
    this.dialog.setMessage("Loading...");
    this.dialog.show();
    dialog.setCanceledOnTouchOutside(false);
    


    protected String[] doInBackground(Object... params) 
        ///
    

    protected void onPostExecute(String [] result) 
    
        super.onPostExecute(result);
        this.dialog.dismiss();
    


你应该这样称呼它:

Task1 myTask = new Task1();    
myTask.execute(stopArrey, start, end);

希望对您有所帮助! :)

【讨论】:

【参考方案2】:

只需要在 UI Thread 上对 ProgressDialog 进行操作。

asynctask 上的构造函数提供了足够的灵活性,可以将任务放入它自己的类中。注意:在您的自定义 AsyncTask 的构造函数中初始化的任何字段都利用 java final 关键字非常重要,因此字段变量会自动为垃圾回收。

解决方案 ProgressDialog 代码需要在 onPreExecute() 中调用,其中任务仍在 UI 线程上。

public class GetCustomerSoapAsync extends AsyncTask<Void, Void, String>

ProgressDialog prg;
// use final for fields initialized in a constructor.
final ActionBarActivity activity;
final GetResponseFromGetCustomer listener;

//下面的例子从调用者那里传入了已经显示的ProgressDialog。将其传入以访问异步任务发布 Progress 方法。在监听器方法中关闭 ProgressDialog;你没有向你的听众展示,所以这只是一种技巧

 public GetCustomerSoapAsync(ActionBarActivity activity, GetResponseFromGetCustomer     listener, ProgressDialog prg)

  this.activity = activity;
  this.listener = listener;
  this.prg = prg;

 // or move this code to onPreExecute() where it runs on the UI thread.
// move this code to onPreExecute() 
//prg = new ProgressDialog(activity);
//prg.setMessage("Lütfen Bekleyin");
//Log.i("ED","Progress will be shown");
//prg.show();


【讨论】:

让我把我的 cmets 放在一起 danny117 和 @SeahawksRdaBest:我尝试了你的建议但仍然没有运气,我正在更新我的问题,因为我认为问题在于我正在尝试显示进度条而我在一个片段里面的一个对话框片段中。我什至尝试在 onPostExecute 中删除 prg.dismiss() 以查看会发生什么,但仍然没有进度条。很有趣。【参考方案3】:

好的,我认为您必须在执行 Aysnch 任务之前在用户可见的布局中声明 PD。

例如:

//Declare the pd here. Pd private to class.
private ProgressDialog pd;
    builder.setMessage("Numaranız doğru mu?\n" + "0" + number)
                    .setPositiveButton(R.string.yes,
                            new DialogInterface.OnClickListener()
                            
                              ....
                             pd = ProgressDialog.show(getActivity(), "",
                            "Your Message Here!!!", false);
                            // Now using a modified constructor call your execute function
                           //Previous parametes + pd
                           GetCustomerSoapAsync gCSA = new GetCustomerSoapAsync(...,...,pd);
                           getCustomerSoapAsync.execute();

    

然后在你的异步类中:

public class GetCustomerSoapAsync extends AsyncTask<Void, Void, String>

  ProgressDialog prg;
  ActionBarActivity activity;
  GetResponseFromGetCustomer listener;


      public GetCustomerSoapAsync(ActionBarActivity activity, GetResponseFromGetCustomer listener,ProgressDialog pd)
      ProgressDialog prg;
      
        this.activity = activity;
        this.listener = listener;
        this.prg = pd;

      



      @Override protected String doInBackground(Void... params)
      
        //some stuff
      

      @Override protected void onPostExecute(String s)
      
        listener.getResponseFromGetCustomer(s);

        if (prg.isShowing())
        
            prg.dismiss();
        

     

Ps:我不知道您是否使用片段作为实现,但如果是,则必须通过 rootview 引用您在片段中的 onclick 函数中调用的同一 pd,否则您可能会在进度对话框中调用函数一开始就没有表现出来。

【讨论】:

以上是关于从 DialogFragment 调用的 AsyncTask 中的 ProgressDialog 未显示的主要内容,如果未能解决你的问题,请参考以下文章

从 DialogFragment 调用的 AsyncTask 中的 ProgressDialog 未显示

从 dialogfragment 调用 onBackPressed 完成活动

使用 DialogFragment 从布局 xml 调用方法。它是如何工作的?

DialogFragment是从Activity还是Fragment打开的?

侦听DialogFragment从ViewPager Fragment中删除事件

DialogFragment 调用失败