如何销毁 CallableTask Android
How to destroy a CallableTask Android
我正在开发一个将图像发送到服务器的应用程序。
我有一个带有取消按钮的 ProgressDialog(有时用户想取消发送)。
方法 "postImage" 调用带有 TaskCallBack 的 CallableTask,TaskCallBack 使用 Retrofit 发送电子邮件。
如果用户单击“取消”按钮,我想终止 CallableTask。
我该怎么做?
Activity代码
public class ListaMenuPrincipalProducao extends ListFragment{
PalmapSvcApi svc;
private int progressBarStatus = 0;
DatabaseManager dbManager;
String[] TextoLista;
// Array of integers points to images stored in /res/drawable/
int[] imagenes;
ListAdapter adapter;
// Array of strings to store currencies
String[] info;
ConnectivityManager mConectivityManager;
int Count_ok=0;
ProgressDialog progressBar;
ProgressDialog SendingDialog;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Each row in the list stores country name, currency and flag
List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
dbManager = new DatabaseManager(getActivity());
mConectivityManager = (ConnectivityManager) getActivity().getSystemService(MainActivity.CONNECTIVITY_SERVICE);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onResume()
{
super.onResume();
svc = PalmapSvc.init(getActivity());
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
else if (position==2)
{
if(mConectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting()) {
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(false);
progressBar.setMessage("Subindo Fotos pro Servidor...");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(getImageCount());
progressBar.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancelar", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
progressBar.dismiss();
}
});
progressBar.show();
}
}
}
}, 30000*getImageCount());
}
postImage(/* xxx */);
}
}
}
}
public void postImage(final long id, final String ImagePath)
{
File image = new File(ImagePath);
final TypedFile typedfile = new TypedFile("image/*",image);
if (svc != null) {
CallableTask.invoke(new Callable<String>() {
@Override
public String call() throws Exception {
String g = svc.updateImage(typedfile, id);
return g;
}
}, new TaskCallback<String>() {
@Override
public void success(String result) {
changeImageStatus(ImagePath);
if(progressBar != null) {
progressBar.setProgress(progressBar.getProgress() + 1);
}
}
@Override
public void error(Exception e) {
Toast.makeText(
getActivity(),
"Erro no envio da Imagem. Tente de novo quando tiver conexão a Internet",
Toast.LENGTH_SHORT).show();
progressBar.dismiss();
}
});
}
boolean isOnline() {
ConnectivityManager manager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
return manager.getActiveNetworkInfo() != null &&
manager.getActiveNetworkInfo().isConnectedOrConnecting();
}
CallableTask
public class CallableTask<T> extends AsyncTask<Void,Double,T> {
private static final String TAG = CallableTask.class.getName();
public static <V> void invoke(Callable<V> call, TaskCallback<V> callback){
new CallableTask<V>(call, callback).execute();
}
private Callable<T> callable_;
private TaskCallback<T> callback_;
private Exception error_;
public CallableTask(Callable<T> callable, TaskCallback<T> callback) {
callable_ = callable;
callback_ = callback;
}
@Override
protected T doInBackground(Void... ts) {
T result = null;
try{
result = callable_.call();
} catch (Exception e){
Log.e(TAG, "Error invoking callable in AsyncTask callable: "+callable_, e);
error_ = e;
}
return result;
}
@Override
protected void onPostExecute(T r) {
if(error_ != null){
callback_.error(error_);
}
else {
callback_.success(r);
}
}
}
TaskCallback
public interface TaskCallback<T> {
public void success(T result);
public void error(Exception e);
}
如果用户单击“取消”按钮,我如何销毁此 CallableTaskBack?
使用线程中断。只要你不在你的任务中进行不可中断的阻塞调用,你所需要的就是正确处理中断条件,就像这样:
// Uses isInterrupted() to keep interrupted status set
if (Thread.currentThread().isInterrupted())
{
// Cannot use InterruptedException since it's checked
throw new RuntimeException();
}
如果你进行不可中断的阻塞调用(比如网络IO),事情会变得更复杂,你需要以某种方式手动中断它们,例如,通过关闭底层套接字。
这里有完整的解决方案:
How can I make shutdown work properly with this custom ExecutorService?
检查这个 link:
我正在开发一个将图像发送到服务器的应用程序。
我有一个带有取消按钮的 ProgressDialog(有时用户想取消发送)。
方法 "postImage" 调用带有 TaskCallBack 的 CallableTask,TaskCallBack 使用 Retrofit 发送电子邮件。
如果用户单击“取消”按钮,我想终止 CallableTask。
我该怎么做?
Activity代码
public class ListaMenuPrincipalProducao extends ListFragment{
PalmapSvcApi svc;
private int progressBarStatus = 0;
DatabaseManager dbManager;
String[] TextoLista;
// Array of integers points to images stored in /res/drawable/
int[] imagenes;
ListAdapter adapter;
// Array of strings to store currencies
String[] info;
ConnectivityManager mConectivityManager;
int Count_ok=0;
ProgressDialog progressBar;
ProgressDialog SendingDialog;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Each row in the list stores country name, currency and flag
List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
dbManager = new DatabaseManager(getActivity());
mConectivityManager = (ConnectivityManager) getActivity().getSystemService(MainActivity.CONNECTIVITY_SERVICE);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onResume()
{
super.onResume();
svc = PalmapSvc.init(getActivity());
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
else if (position==2)
{
if(mConectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting()) {
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(false);
progressBar.setMessage("Subindo Fotos pro Servidor...");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(getImageCount());
progressBar.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancelar", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
progressBar.dismiss();
}
});
progressBar.show();
}
}
}
}, 30000*getImageCount());
}
postImage(/* xxx */);
}
}
}
}
public void postImage(final long id, final String ImagePath)
{
File image = new File(ImagePath);
final TypedFile typedfile = new TypedFile("image/*",image);
if (svc != null) {
CallableTask.invoke(new Callable<String>() {
@Override
public String call() throws Exception {
String g = svc.updateImage(typedfile, id);
return g;
}
}, new TaskCallback<String>() {
@Override
public void success(String result) {
changeImageStatus(ImagePath);
if(progressBar != null) {
progressBar.setProgress(progressBar.getProgress() + 1);
}
}
@Override
public void error(Exception e) {
Toast.makeText(
getActivity(),
"Erro no envio da Imagem. Tente de novo quando tiver conexão a Internet",
Toast.LENGTH_SHORT).show();
progressBar.dismiss();
}
});
}
boolean isOnline() {
ConnectivityManager manager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
return manager.getActiveNetworkInfo() != null &&
manager.getActiveNetworkInfo().isConnectedOrConnecting();
}
CallableTask
public class CallableTask<T> extends AsyncTask<Void,Double,T> {
private static final String TAG = CallableTask.class.getName();
public static <V> void invoke(Callable<V> call, TaskCallback<V> callback){
new CallableTask<V>(call, callback).execute();
}
private Callable<T> callable_;
private TaskCallback<T> callback_;
private Exception error_;
public CallableTask(Callable<T> callable, TaskCallback<T> callback) {
callable_ = callable;
callback_ = callback;
}
@Override
protected T doInBackground(Void... ts) {
T result = null;
try{
result = callable_.call();
} catch (Exception e){
Log.e(TAG, "Error invoking callable in AsyncTask callable: "+callable_, e);
error_ = e;
}
return result;
}
@Override
protected void onPostExecute(T r) {
if(error_ != null){
callback_.error(error_);
}
else {
callback_.success(r);
}
}
}
TaskCallback
public interface TaskCallback<T> {
public void success(T result);
public void error(Exception e);
}
如果用户单击“取消”按钮,我如何销毁此 CallableTaskBack?
使用线程中断。只要你不在你的任务中进行不可中断的阻塞调用,你所需要的就是正确处理中断条件,就像这样:
// Uses isInterrupted() to keep interrupted status set
if (Thread.currentThread().isInterrupted())
{
// Cannot use InterruptedException since it's checked
throw new RuntimeException();
}
如果你进行不可中断的阻塞调用(比如网络IO),事情会变得更复杂,你需要以某种方式手动中断它们,例如,通过关闭底层套接字。
这里有完整的解决方案:
How can I make shutdown work properly with this custom ExecutorService?
检查这个 link: