我的Android应用将大量文件发送到Amazon S3。每个文件URI都通过单独的调用传递给执行上传的IntentService
。
但是,我想知道处理故障的最佳方法是什么......我应该用IntentService
的{{1}}方法检测到失败并在同一方法中重试,或者我应该允许在方法之外处理失败(如果是,如何处理?)?
我个人倾向于第一个建议,因为我希望在尝试上传后续文件之前成功上传任何文件,但我不确定是否在onHandleIntent()
方法中检测错误并执行重试是好的做法(?)。
答案 0 :(得分:5)
这是一个非常好的问题。我在一次采访中被问到这个问题而我没有回答。但在寻找答案之后,我会尝试在这里回答。
步骤1:启动IntentService。您可以从Activity或Fragment启动IntentService。
/* Starting Download Service */
DownloadResultReceiver mReceiver = new DownloadResultReceiver(new Handler());
mReceiver.setReceiver(this);
Intent intent = new Intent(Intent.ACTION_SYNC, null, this, DownloadService.class);
/* Send optional extras to Download IntentService */
intent.putExtra("url", url);
intent.putExtra("receiver", mReceiver);
intent.putExtra("requestId", 101);
startService(intent);
Step-2:创建扩展IntentService的类。
public class DownloadService extends IntentService {
public static final int STATUS_RUNNING = 0;
public static final int STATUS_FINISHED = 1;
public static final int STATUS_ERROR = 2;
private static final String TAG = "DownloadService";
public DownloadService() {
super(DownloadService.class.getName());
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "Service Started!");
final ResultReceiver receiver = intent.getParcelableExtra("receiver");
String url = intent.getStringExtra("url");
Bundle bundle = new Bundle();
if (!TextUtils.isEmpty(url)) {
/* Update UI: Download Service is Running */
receiver.send(STATUS_RUNNING, Bundle.EMPTY);
try {
String[] results = downloadData(url);//make your network call here and get the data or download a file.
/* Sending result back to activity */
if (null != results && results.length > 0) {
bundle.putStringArray("result", results);
receiver.send(STATUS_FINISHED, bundle);
}
} catch (Exception e) {
/* Sending error message back to activity */
bundle.putString(Intent.EXTRA_TEXT, e.toString());
receiver.send(STATUS_ERROR, bundle);
}
}
Log.d(TAG, "Service Stopping!");
this.stopSelf();
}
}
步骤3:要从IntentService接收结果,我们可以使用ResultReciever的子类。从Service发送结果后,将调用onReceiveResult()方法。您的活动处理此响应并从Bundle中获取结果。收到结果后,活动实例会相应地更新UI。
public class DownloadResultReceiver extends ResultReceiver {
private Receiver mReceiver;
public DownloadResultReceiver(Handler handler) {
super(handler);
}
public void setReceiver(Receiver receiver) {
mReceiver = receiver;
}
public interface Receiver {
public void onReceiveResult(int resultCode, Bundle resultData);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (mReceiver != null) {
mReceiver.onReceiveResult(resultCode, resultData);
}
}
}
步骤4:在您的MainActivity中:
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
switch (resultCode) {
case DownloadService.STATUS_RUNNING:
//progress bar visible.
break;
case DownloadService.STATUS_FINISHED:
/* Hide progress & extract result from bundle */
/* Update ListView with result */
break;
case DownloadService.STATUS_ERROR:
/* Handle the error */
String error = resultData.getString(Intent.EXTRA_TEXT);
Toast.makeText(this, error, Toast.LENGTH_LONG).show();
/*It is here, i think, that you can again check (eg your net connection) and call the IntentService to restart fetching of data from the network. */
break;
}
}
我希望上面的答案可以帮到你。任何改善答案的建议都是最受欢迎的。谢谢。