我的第一個解決方案是使用具有接口實現的回調方法,請參閱示例https://stackoverflow.com/a/6396376/390177。
在Android聊天中聊了一會之後,我聽說有一種更可行的解決方案。
您可以使用IntentService結合PendingIntent。
通訊實現意圖's。
如果你想使用ProgressDialog,你需要爲它的自己的活動,其註冊例如BroadcastReciever和IntentService將它基於廣播的實際狀態。
但是讓我們現在就開始。
首先,我們創建了活動,其中包含ProgressDialog和註冊廣播接收器。該廣播接收器聽取有關更新和整理對話框消息。
對於活動我們需要佈局...
<?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可用的,所以我們在活動創建的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);
對於接收結果,我們必須重寫方法onActivityResult(int requestCode, int resultCode, Intent data)
。
@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));
}
}
}
這是神奇的,我希望它會幫助你。
那裏,在哪裏?我對活動描述感到困惑。你能寫一些名字,而不是使用「there」,所以我們知道我們正在查看多少不同的活動,謝謝其他人,只是在你的問題中轉儲相關的代碼:) – doNotCheckMyBlog
我已經編輯過問。我希望現在清楚。通常只有主* Activity *,它調用writeEntry()方法。 – CSchulz
我試圖理解它,所以基本上你有wrtieEntry方法執行AsyncTask但(writeEntry)代碼執行不斷。但是你希望代碼等到asynctask完成它的工作。我對嗎? – doNotCheckMyBlog