0

我发现的每个教程似乎都使用 AsyncTask(已弃用)而不是 ExecutorService。我参加了关于 Udemy 的 Java 课程,他们也使用 AsyncTask 处理所有内容。这是我正在使用的一门课:

public class FetchURL extends AsyncTask<String, Void, String> {
Context mContext;
String directionMode = "driving";

public FetchURL(Context mContext) {
    this.mContext = mContext;
}

@Override
protected String doInBackground(String... strings) {
    // For storing data from web service
    String data = "";
    directionMode = strings[1];
    try {
        // Fetching the data from web service
        data = downloadUrl(strings[0]);
        Log.d("mylog", "Background task data " + data.toString());
    } catch (Exception e) {
        Log.d("Background Task", e.toString());
    }
    return data;
}

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    PointsParser parserTask = new PointsParser(mContext, directionMode);
    // Invokes the thread for parsing the JSON data
    parserTask.execute(s);
}

private String downloadUrl(String strUrl) throws IOException {
    String data = "";
    InputStream iStream = null;
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(strUrl);
        // Creating an http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();
        // Connecting to url
        urlConnection.connect();
        // Reading data from url
        iStream = urlConnection.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
        StringBuffer sb = new StringBuffer();
        String line = "";
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        data = sb.toString();
        Log.d("mylog", "Downloaded URL: " + data.toString());
        br.close();
    } catch (Exception e) {
        Log.d("mylog", "Exception downloading URL: " + e.toString());
    } finally {
        iStream.close();
        urlConnection.disconnect();
    }
    return data;
}
}

我真的很想在这里使用 ExecutorService而不是 AsyncTask。我正在用头撞墙,我似乎无法提出正确的论点并且这件事起作用了。

4

1 回答 1

0

将您的替换AsyncTaskRunnable

public class FetchUrl implements Runnable {

    public interface Callback {
        void onSuccess(String data);
        void onFailure(Exception e);
    }

    private String url;
    private WeakReference<Callback> callbackWeakReference;

    public FetchUrl(String url, Callback callback) {
        this.url = url;
        this.callbackWeakReference = new WeakReference<>(callback);
    }

    @Override
    public void run() {
        try {
            String data = downloadUrl(url);
            Callback callback = callbackWeakReference.get();
            if (callback != null) {
                callback.onSuccess(data);
            }
        } catch (Exception e) {
            Callback callback = callbackWeakReference.get();
            if (callback != null) {
                callback.onFailure(e);
            }
        }
    }
    
    ... // include your downloadUrl function
}

然后创建并提交给ExecutorService

FetchUrl.Callback callback = new FetchUrl.Callback() {
    @Override
    public void onSuccess(String data) {
        // handle your data
    }

    @Override
    public void onFailure(Exception e) {
        // handle the exception
    }
};
Runnable job = new FetchUrl(url, callback);

ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.submit(job);

请注意,我使用了WeakReference<Callback>,因为您的回调中的代码持有对的引用Context并会导致Context泄漏。

submit()函数返回一个Future来控制您提交的作业。如果您想取消作业或等待其完成(阻塞当前线程),这很方便。后一个用例可能更倾向于使用Callable<Result>而不是Runnable,因为调用线程可以处理异常,并且没有使用回调使您的代码更简洁。

当您不再需要它时,也不要忘记打电话shutdown()给您。ExecutorService

于 2020-08-16T09:21:53.853 回答