Android:使用AsyncTask进行进度对话

时间:2013-12-08 09:33:20

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

由于游戏需要TTS,并且需要相当长的时间来加载,我想以下列方式实现进度对话(PD),

在Game Index Page中实现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的AsyncTask:

从游戏索引页面点击后,在完全加载游戏之前不会显示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/

这样的网站

谢谢你的时间!

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

如果我从您的问题中正确理解,加载Game_star_intro活动会花费大量时间,因为您在创建此活动时使用TTS。你使用的代码是错误的。当另一个活动正在运行(或正在创建)时,Index_game的ProgressDialog将不会显示。您应该在AsyncTask活动中使用Game_star_intro并在那里使用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();
        }      
    }
}