如何解决等待带有ProgressDialog的已执行AsyncTask
| 我有一个方法public void writeEntry(Activity ctx,Entry entry)
,它获取一些数据并必须调用一个本机方法,这需要花费更长的时间才能完成。
因此,我创建了一个处理ProgressDialog和本机方法的AsyncTask。它可以在自己的Activity中很好地进行测试,因为该Activity我使用了回调接口,依此类推。
就我而言,我具有上述方法,必须执行AsyncTask。执行不能在该方法中,因为它不会停止进一步的执行。
在继续执行之前,需要本机方法的结果。
是否有可能等待AsyncTask直到完成? wait()
方法不是一个选项,因为UI线程也将等待,因此将失去ProgressDialog的意义。
我可以使用给定参数中的方法“ 2”吗?还是启动自己的Activity的唯一解决方案?
解决方法
所以我会尽力解释
在AsyncTask中启动繁重的过程,但是要在AsyncTask完成后要执行的任何代码都将其放在单独的公共方法中。现在,一旦完成繁重的过程调用,便会在
onPostExecute()
中单独创建一个方法。
所以psuuedo代码看起来像这样,
class main extends Activity {
class Something extends AsyncTask<String,Integer,String> {
protected void onPreExecute() {
// Start your progress bar...
}
protected String doInBackground(String... params) {
// Do your heavy stuff...
return null;
}
protected void onPostExecute(String result) {
// close your progress dialog and than call method which has
// code you are wishing to execute after AsyncTask.
}
}
}
希望这会有所帮助,
祝好运!
, 我的第一个解决方案是在接口实现中使用回调方法,请参见示例https://stackoverflow.com/a/6396376/390177。
在Android聊天中聊天了一段时间后,我听说有一个更实用的解决方案。
您可以将IntentService与PendingIntent结合使用。
通信是用Intent \'s实现的。
如果要使用ProgressDialog,则需要一个自己的Activity,例如,它注册一个BroadcastReciever,并且IntentService每次广播都会向其发送实际状态。
现在开始吧。
首先,我们创建活动,其中包含ProgressDialog和已注册的BroadcastReceiver。 BroadcastReceiver侦听有关更新和完成对话框的消息。
对于活动,我们需要布局...
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\" android:layout_height=\"match_parent\"
android:background=\"#80000000\">
</LinearLayout>
...以及相关代码:
public class ProgressActivity extends Activity {
/**
* ProgressDialog which is shown
*/
private ProgressDialog progessDialog_g;
/**
* Instance of the BroadcastReceiver
*/
private BroadcastReceiver receiver_g;
/**
* Identifier for the different settings of the ProgressDialog
*/
public static final String PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR = \"pbar_horizontal_bar\";
public static final String PROGRESS_DIALOG_BOOL_CANCELABLE = \"pbar_horizontal_cancelable\";
public static final String PROGRESS_DIALOG_STR_MESSAGE = \"pbar_message\";
public static final String PROGRESS_DIALOG_INT_MAX = \"pbar_max_bar\";
public static final String PROGRESS_DIALOG_INT_VALUE = \"pbar_value\";
protected static final int PROGRESS_DIALOG_INT_MAX_VALUE = 100;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
progessDialog_g = new ProgressDialog(this);
// Reads and sets the settings for the ProgressDialog
Intent i = getIntent();
progessDialog_g.setCancelable(i.getBooleanExtra(
PROGRESS_DIALOG_BOOL_CANCELABLE,false));
if (i.getBooleanExtra(
PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR,false)) {
progessDialog_g.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
} else {
progessDialog_g.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
progessDialog_g
.setMessage(i
.getStringExtra(PROGRESS_DIALOG_STR_MESSAGE));
progessDialog_g.setMax(i.getIntExtra(
PROGRESS_DIALOG_INT_MAX,100));
// Create the IntentFilter for the different broadcast messages
IntentFilter iFilter =
new IntentFilter(
ExampleProgressService.PROGRESS_DIALOG_BROADCAST_INIT);
iFilter.addAction(ExampleProgressService.PROGRESS_DIALOG_BROADCAST_UPDATE);
iFilter.addAction(ExampleProgressService.PROGRESS_DIALOG_BROADCAST_FINISH);
// Creates the BroadcastReceiver
receiver_g = new BroadcastReceiver() {
@Override
public void onReceive(Context context,Intent intent){
Log.d(DefaultPreferences.DEBUG_PREFIX + \"ProgressActivity\",intent.getAction());
if (ExampleProgressService.PROGRESS_DIALOG_BROADCAST_INIT
.equals(intent.getAction())) {
// Sets the ProgressDialog style
if (intent
.getBooleanExtra(
PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR,false)) {
progessDialog_g
.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
} else {
progessDialog_g
.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
// Shows the ProgressDialog
progessDialog_g.show();
} else if (ExampleProgressService.PROGRESS_DIALOG_BROADCAST_UPDATE
.equals(intent.getAction())) {
// Updates the ProgressDialog
int value =
intent.getIntExtra(
PROGRESS_DIALOG_INT_VALUE,-1);
if (value != -1) {
progessDialog_g.setProgress(value);
}
} else if (ExampleProgressService.PROGRESS_DIALOG_BROADCAST_FINISH
.equals(intent.getAction())) {
// Finishs the ProgressDialog
progessDialog_g.cancel();
finish();
}
}
};
// Registers the BroadcastReceiver
registerReceiver(receiver_g,iFilter);
}
@Override
protected void onDestroy(){
unregisterReceiver(receiver_g);
super.onDestroy();
}
}
现在我们要使用活动,因此让我们从调用它开始:
final Intent i = new Intent(parentActivity,<packages>.ProgressActivity);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_BOOL_CANCELABLE,cancelable_g);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR,showProgress_g);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_STR_MESSAGE,message_g);
i.putExtra(ProgressActivity.PROGRESS_DIALOG_INT_MAX,ProgressActivity.PROGRESS_DIALOG_INT_MAX_VALUE);
parentActivity.startActivity(i);
因此,我们有一个正在运行的ProgressActivity,它需要等待不同的广播。但是首先我们需要IntentService,它可以发送广播。
所以放手:
public class ExampleProgressService extends IntentService {
/**
* PendingIntent for callback.
*/
protected PendingIntent pi_g = null;
private static final String DEBUG_TAG = \"ExampleProgressService\";
/**
* Message identifier for ProgressDialog init
*/
public static final String PROGRESS_DIALOG_BROADCAST_INIT = \"Dialog.Progress.Init\";
/**
* Message identifier for ProgressDialog finish
*/
public static final String PROGRESS_DIALOG_BROADCAST_FINISH = \"Dialog.Progress.Finish\";
/**
* Message identifier for ProgressDialog update
*/
public static final String PROGRESS_DIALOG_BROADCAST_UPDATE = \"Dialog.Progress.Update\";
/**
* Identifier of the result for intent content
*/
public static final String PROGRESS_DATA_RESULT = \"Result\";
/**
* Identifier of the result error for intent content
*/
public static final String PROGRESS_DATA_RESULT_ERROR_MESSAGE = \"Result.Error.Message\";
/**
* Identifier of the result error exception for intent content
*/
public static final String PROGRESS_DATA_RESULT_ERROR_EXCEPTION = \"Result.Error.Exception\";
/**
* Identifier of the result status for intent content
*/
public static final String PROGRESS_DATA_RESULT_STATUS_BOOL = \"Result.Status.boolean\";
/**
* Identifier of the pending intent for intent content
*/
public static final String PROGRESS_DATA_PENDING_RESULT = \"PendingResult\";
public ExampleProgressService() {
super(\"ExampleProgressService\");
}
/**
* Send the finish message.
*/
private void closeProgressActivity() {
Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_FINISH);
sendBroadcast(intent);
}
/**
* Do some magic with the intent content
*/
private void extractVariablesFromIntentAndPrepare(Intent intent)
throws Exception {
pi_g = (PendingIntent) intent
.getParcelableExtra(PROGRESS_DATA_PENDING_RESULT);
if (pi_g == null) {
throw new Exception(\"There is no pending intent!\");
}
/**
* Sends an error message.
*/
private void failed(Exception e,String message) {
Intent i = new Intent();
i.putExtra(PROGRESS_DATA_RESULT_ERROR_EXCEPTION,e);
i.putExtra(PROGRESS_DATA_RESULT_ERROR_MESSAGE,message);
send(i,false);
}
/**
* Sends the init message.
*/
private void initProgressActivity() {
Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_INIT);
intent.putExtra(PROGRESS_DIALOG_BOOL_HORIZONTAL_BAR,multipart_g);
sendBroadcast(intent);
}
/**
* (non-Javadoc)
*
* @see android.app.IntentService#onHandleIntent(android.content.Intent)
*/
@Override
protected void onHandleIntent(Intent intent) {
extractVariablesFromIntentAndPrepare(intent);
initProgressActivity();
// do your calculation here and implements following code
Intent intent = new Intent(PROGRESS_DIALOG_BROADCAST_UPDATE);
intent.putExtra(PROGRESS_DIALOG_INT_VALUE,progressValue);
sendBroadcast(intent);
// If you finished,use one of the two methods to send the result or an error
success(result);
failed(exception,optionalMessage);
}
/**
* Sends the data to the calling Activity
*/
private void send(Intent resultData,boolean status) {
resultData.putExtra(PROGRESS_DATA_RESULT_STATUS_BOOL,status);
closeProgressActivity();
try {
pi_g.send(this,Activity.RESULT_OK,resultData);
} catch (PendingIntent.CanceledException e) {
Log.e(DEBUG_TAG,\"There is something wrong with the pending intent\",e);
}
}
/**
* Sends the result message.
*/
private void success(String result) {
Intent i = new Intent();
i.putExtra(PROGRESS_DATA_RESULT,result);
send(i,true);
}
}
计算进度的结果应在parentActivity中可用,因此我们在该Activity中创建PendingIntent并调用IntentService。
// Some identifier for the call
int requestCode = 12345;
final Intent sI = new Intent(ExampleProgressService.PROGRESS_SERVICE_ACTION);
// Callback
sI.putExtra(ExampleProgressService.PROGRESS_DATA_PENDING_RESULT,parentActivity
.createPendingResult(requestCode,null,PendingIntent.FLAG_CANCEL_CURRENT));
// Service start
parentActivity.startService(sI);
为了接收结果,我们必须重写方法“ 10”。
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
// Compares the requestCode with the requestCode from above
if (requestCode == ...) {
if (data.getBooleanExtra(ExampleProgressService.PROGRESS_DATA_RESULT_STATUS_BOOL,false)) {
// Calculation was success
data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT);
} else
{
// Calculation is failed
data.getStringExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_MESSAGE);
((Exception) data.getSerializableExtra(ExampleProgressService.PROGRESS_DATA_RESULT_ERROR_EXCEPTION));
}
}
}
那是魔术,我希望它能对您有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。