【问题标题】:Android: Progress Dialog with AsyncTaskAndroid:带有 AsyncTask 的进度对话框
【发布时间】:2013-12-08 09:33:20
【问题描述】:

由于游戏需要 TTS,并且需要很长时间才能加载,所以我想通过以下方式任一实现进度对话框 (PD):

在游戏索引页面中实现 AsyncTask:

这会显示PD,但是PD被冻结了,即PD内部的循环圈没有循环。

    buttonC.setOnClickListener(new OnClickListener() 
    {  
        @Override
        public void onClick(View v) 
        {
            new initialize_game().execute();
        }
    }); 


private class initialize_game extends AsyncTask<String,Integer,String> 
{
    @Override
    protected void onPreExecute()
    {           
        dialog= new ProgressDialog(Index_game.this);
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.setMessage("Loading!\nPlease wait...");
        dialog.show();
    }

    @Override
    protected String doInBackground(String... params) 
    {            
        buttonC.setBackgroundColor(getResources().getColor(R.color.tran_black));
        Intent intent = new Intent(Index_game.this, Game_star_intro.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        startActivityForResult(intent, 0);
        overridePendingTransition(0, 0); // 0 for no animation
        Index_game.this.finish();   
        return "Done!";
    }

    protected void onPostExecute(String result) 
    {

        super.onPostExecute(result);
        Log.i("result","" +result);
        if(result!=null)
        {
            dialog.dismiss();
        }      
    }
}

TTS 的异步任务:

从游戏索引页面点击后,直到游戏完全加载后才会显示 PD,此时 PD 会弹出并关闭一毫秒,即比上面的更糟。

private class MainFrameTask extends AsyncTask<String,Integer,String> implements OnInitListener, OnUtteranceCompletedListener
{
    private Index_game_card_intro mainFrame = null;  

    public MainFrameTask(Index_game_card_intro mainFrame)
    {  
        this.mainFrame = mainFrame;  
    }  

    @Override  
    protected void onCancelled() 
    {  
        stopProgressDialog();  
        super.onCancelled();  
    }  

    @Override
    protected void onPreExecute()
    {           
        startProgressDialog(); 
    }

    @Override
    protected String doInBackground(String... params) 
    {            
        // setup TTS part 1.1
          mTts = new TextToSpeech(Index_game_card_intro.this, this);  // TextToSpeech.OnInitListener



        return "Done!";
    }

    protected void onPostExecute(String result) 
    {
        stopProgressDialog();      
    }

 // setup TTS part 2    
    @Override
    public void onUtteranceCompleted(String utteranceId) 
    {  
        Log.v(TAG, "Get completed message for the utteranceId " + utteranceId);  
        lastUtterance = Integer.parseInt(utteranceId);  
    }  

// setup TTS part 3 
    @Override
    public void onInit(int status) 
    {  
        if(status == TextToSpeech.SUCCESS)  
        {  
            int result = mTts.setLanguage(Locale.US);  // <====== set speech location
            mTts.setSpeechRate((float) 0.8);
            mTts.setPitch(1.0f);
            if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)  
            {  
                // button_header.setEnabled(false);  
            }  
            else  
            {  
                // button_header.setEnabled(true);  
                mTts.setOnUtteranceCompletedListener(this);  
            }  
        }     
    }    
}

// setup TTS part 4 
private void speakText()  
{  
    lastUtterance++;  
    if(lastUtterance >= loveArray.length)  
    {  
        lastUtterance = 0;  
    }  
    Log.v(TAG, "the begin utterance is " + lastUtterance);  
    for(int i = lastUtterance; i < loveArray.length; i++)  
    {  
        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.valueOf(i));  
        mTts.speak(loveArray[i], TextToSpeech.QUEUE_ADD, params);  
        mTts.playSilence(ttsilience, TextToSpeech.QUEUE_ADD, null);
    }  
} 

问题:

我发现当按下游戏索引中的按钮 C 时,进度对话框没有显示出来。但是,当Game_star_intro 最终加载时,进度对话框会弹出很短的时间然后就消失了。

我想在加载游戏时显示 ProgressDialog,而不是在加载游戏后对话框弹出一毫秒。

这样,我也试过把负载TTS放在AsyncTask里面Game_star_intro里面,结果还是一样:对话框只弹出一毫秒。

其实AsyncTask应该怎么编码??我关注了这样的网站http://karanbalkar.com/2012/10/tutorial-5-custom-progressdialog-with-asynctask/

感谢您的宝贵时间!

【问题讨论】:

标签: android android-asynctask text-to-speech progressdialog


【解决方案1】:

您不应该在后台线程中启动您的活动。例如,在您的 onClick() 方法中启动它。您应该只将昂贵的代码放在doInBackground() 中,将其与框架生命周期的东西分开。我想你应该为此在Game_star_intro 类中实现AsyncTask

ProgressDialog 没有显示可能是因为 UI 线程在工作完成之前被冻结。

此外,Java 中的命名约定建议名称类不带下划线,即 GameStarIntro :)

【讨论】:

  • 感谢您的建议。我现在尝试在Game_star_intro 内的doInBackground 中移动加载TTS。然而我测试发现,在游戏索引页面中按下按钮C时,它会在加载时间挂起,然后当Game_star_intro加载时,进度对话框只是弹出一秒钟,页面准备好说话了。 UI线程被冻结了?
  • developer.android.com/guide/components/… "具体来说,如果一切都发生在UI线程中,执行网络访问或数据库查询等长时间操作会阻塞整个UI。当线程被阻塞时,无法调度任何事件,包括绘图事件。从用户的角度来看,应用程序似乎挂起。”我假设您可能看不到您的对话框,因为 UI 线程被阻止,即冻结。
  • 是的,我现在明白你的意思了。以这种方式,在我的 ProgressDialog (PD) 中,有一个循环的 imageview。如果我将 AsyncTask 放在 game_index 页面,ProgressDialog 会出现,但 imageview 不会循环。然而,如果我输入Game_star_intro,PD 甚至不会出现,直到 TTS 被加载,然后 PD 在一毫秒内弹出并关闭。因此,似乎加载 TTS 会阻止 UI
  • 所以,我想,这应该被标记为已回答?我认为 TTS 的问题值得提出一个不同的问题,并发布了 TTS 代码。
【解决方案2】:

如果我从您的问题中正确理解,加载 Game_star_intro 活动需要很长时间,因为您在创建此活动时使用了 TTS。您使用的代码是错误的。当另一个活动正在运行(或正在创建)时,来自Index_game 的 ProgressDialog 将不会显示。您应该在 Game_star_intro 活动中使用 AsyncTask 并在那里使用 TTS。在Index_game 开始Game_star_intro

buttonC.setOnClickListener(new OnClickListener() 
{  
    @Override
    public void onClick(View v) 
    {
        Intent intent = new Intent(Index_game.this, Game_star_intro.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        startActivityForResult(intent, 0);
    }
});

Game_star_intro 中是这样的

public void onCreate() {
    ...
    new TTLTask().execute();
}

private class TTLTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute()
    {           
        dialog= new ProgressDialog(Index_game.this);
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.setMessage("Loading!\nPlease wait...");
        dialog.show();
    }

    @Override
    protected String doInBackground(String... params) 
    {            
        //... TTS code
        return null;
    }

    protected void onPostExecute(String result) 
    {

        super.onPostExecute(result);
        Log.i("result","" +result);
        if(dialog.isShown())
        {
            dialog.dismiss();
        }      
    }
}

【讨论】:

  • 非常感谢您的回复!我已经尝试通过将 AsyncTask 切换为在 doInBackground 内的 Game_star_intro 中加载 TTS 来实现这种方式。我测试发现,在游戏索引页面按下按钮C时,加载时间挂起,然后在加载Game_star_intro时,进度对话框只弹出一秒钟,页面就可以说话了。
  • 我想问题不在于这个 AsyncTask,而在于其他地方。 TextToSpeach 的创建速度很快。这就是为什么 PD 只弹出一秒钟的原因。尝试在执行任务的地方之前找到原因。
猜你喜欢
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多