Android 替换嵌套的异步任务

Android 替换嵌套的异步任务,android,android-asynctask,nested,Android,Android Asynctask,Nested,在我的Android应用程序中,我有几个活动都连接到一个服务。此服务建立与服务器的连接,并处理数据(大多数情况下为xml文件)的发送和检索。在我的活动中,我调用AsyncTask中的服务函数,因为我需要根据服务器的应答执行以下操作。以下是该结构的一个示例: String xmlString = "<myXmlString><myDataObject></myDataObject></myXmlString>"; final AsyncTask&l

在我的Android应用程序中,我有几个活动都连接到一个服务。此服务建立与服务器的连接,并处理数据(大多数情况下为xml文件)的发送和检索。在我的活动中,我调用AsyncTask中的服务函数,因为我需要根据服务器的应答执行以下操作。以下是该结构的一个示例:

String xmlString = "<myXmlString><myDataObject></myDataObject></myXmlString>";

final AsyncTask<Void, Void, Boolean> myTask = new AsyncTask<Void, Void, Boolean>() {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        showProgressDialog("Send Data...");
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        int rc = mService.callMethod("MYFUNCTION", xmlString);
        if (rc == 0) {
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    protected void onPostExecute(Boolean success) {
        hideProgressDialog();

        if (success) {
            // handle received data
            // here it also might occur that another AsyncTask is called
            // e.g.: final AsyncTask<Void, Void, Boolean> nestedTask = new AsyncTask<Void, Void, Boolean>() { ... }
        } else {
            // handle error
        }
    }
};

myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Handler handler = new Handler();
Runnable taskCanceler = new Runnable() {
    @Override
    public void run() {
        if (myTask.getStatus() == AsyncTask.Status.RUNNING) {
            myTask.cancel(true);

            hideProgressDialog();
        }
    }
};
handler.postDelayed(taskCanceler, 15000);
String xmlString=”“;
final AsyncTask myTask=新建AsyncTask(){
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
showProgressDialog(“发送数据…”);
}
@凌驾
受保护的布尔doInBackground(Void…params){
int rc=mService.callMethod(“MYFUNCTION”,xmlString);
如果(rc==0){
返回true;
}
否则{
返回false;
}
}
@凌驾
受保护的void onPostExecute(布尔值成功){
hideProgressDialog();
如果(成功){
//处理接收到的数据
//这里还可能发生调用另一个AsyncTask的情况
//例如:final AsyncTask nestedTask=new AsyncTask(){…}
}否则{
//处理错误
}
}
};
myTask.executeOnExecutor(异步任务.线程池执行器);
Handler=newhandler();
Runnable taskCanceler=new Runnable(){
@凌驾
公开募捐{
if(myTask.getStatus()==AsyncTask.Status.RUNNING){
myTask.cancel(true);
hideProgressDialog();
}
}
};
handler.postDelayed(taskCanceler,15000);
因为我更新了Android Studio,它说“这个异步任务应该是静态的,否则可能会发生泄漏”。此外,嵌套的AsyncTasks有时会非常混乱,但它们相互依赖,所以我真的不知道如何将这些任务更改为静态类。我应该使用不同的方法来满足我的需求,还是可以将它们转换为静态类,并且仍然保持嵌套逻辑的活性


我希望我能把我的问题说清楚。提前谢谢

您似乎愿意更改web服务访问逻辑

您应该阅读关于Rxjava/RxKotlin的内容,并使用这些技术进行快速重构。 一开始,这看起来很复杂,但相信我,一旦接收,你就再也回不去了


您似乎愿意更改web服务访问逻辑

您应该阅读关于Rxjava/RxKotlin的内容,并使用这些技术进行快速重构。 一开始,这看起来很复杂,但相信我,一旦接收,你就再也回不去了


如果您了解基本线程,就不用为异步任务操心了。AsyncTasks是帮助者,但帮助不大。在您的服务中添加以下内容。您通常会传递一个共享接口(lambda在这里会很好,但遗憾的是Java7),该接口将在响应时触发。然后服务会为您执行线程处理。毕竟,在服务与服务器对话的情况下,这种情况总会发生。无论如何,它总是需要在一个线程中这样做

    HttpFetch.get(url, new UIResponse() {
        @Override
        public void response(String header, String content) {
        }
    },this);
由于它使用一个静态类进行Http工作,因此没有泄漏,您可以调用它并获取所需的响应数据。因为它是同一个静态类,你显然可以把它们放在你的心上。因此,为响应向它发送一个请求和一个类,并实现响应类

例如,下面是我做那件事时的其他内容:

public static void get(final URL urir, final Response response, final Activity activity) {
    Runnable run = new Runnable() {
        @Override
        public void run() {
            HttpURLConnection urlConnection = null;
            try {
                urlConnection = (HttpURLConnection) urir.openConnection();
                InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
                final String content = convertStreamToString(stream);
                final String header = urlConnection.getResponseMessage();
                stream.close();

                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        response.response(header, content);
                    }
                });
            } catch (final IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        response.error(e);
                    }
                });
            } finally {
                if (urlConnection != null) urlConnection.disconnect();
            }
        }
    };
    Thread thread = new Thread(run);
    thread.start();
}

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}


public interface Response {
    void response(String header, String content);
    void error(IOException exception);
}

像RxJava这样的其他类可能也在做同样的事情。只要交给它一个带有响应函数的请求,并在服务中执行线程,您就成功了。

如果您了解基本线程,就不必为异步任务操心了。AsyncTasks是帮助者,但帮助不大。在您的服务中添加以下内容。您通常会传递一个共享接口(lambda在这里会很好,但遗憾的是Java7),该接口将在响应时触发。然后服务会为您执行线程处理。毕竟,在服务与服务器对话的情况下,这种情况总会发生。无论如何,它总是需要在一个线程中这样做

    HttpFetch.get(url, new UIResponse() {
        @Override
        public void response(String header, String content) {
        }
    },this);
由于它使用一个静态类进行Http工作,因此没有泄漏,您可以调用它并获取所需的响应数据。因为它是同一个静态类,你显然可以把它们放在你的心上。因此,为响应向它发送一个请求和一个类,并实现响应类

例如,下面是我做那件事时的其他内容:

public static void get(final URL urir, final Response response, final Activity activity) {
    Runnable run = new Runnable() {
        @Override
        public void run() {
            HttpURLConnection urlConnection = null;
            try {
                urlConnection = (HttpURLConnection) urir.openConnection();
                InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
                final String content = convertStreamToString(stream);
                final String header = urlConnection.getResponseMessage();
                stream.close();

                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        response.response(header, content);
                    }
                });
            } catch (final IOException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        response.error(e);
                    }
                });
            } finally {
                if (urlConnection != null) urlConnection.disconnect();
            }
        }
    };
    Thread thread = new Thread(run);
    thread.start();
}

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}


public interface Response {
    void response(String header, String content);
    void error(IOException exception);
}

像RxJava这样的其他类可能也在做同样的事情。只要交给它一个带有响应功能的请求,并在服务中执行线程,你就成功了。

Asyntasks是作为后台同步方法引入的,它能够在结果完成后将结果发布到主线程。然而,当逻辑复杂时,它们有很大的局限性

它们很难正确地取消,如果使用不正确,它们可能会泄漏内存,并且在有多个操作要运行时使用起来很麻烦

最后,它们对您可以同时执行的数量有严格限制

您将找到一个库列表,可以将其用作Asynctask的替代品

如果您是一位经验更丰富的程序员,那么我建议您先走一步,使用以下技术之一:

:这是过去几年安卓开发的主流。它将帮助您以反应式的方式处理业务逻辑和API调用。开始时,学习曲线相当陡峭,但后来会让你的生活更轻松。 这是一个介绍


Kotlin协程:如果您喜欢Kotlin协程,它提供了一种处理并发的简单方法。您可以在这里找到一些asyntask,它们是作为后台同步方法引入的,能够在结果完成时将结果发布到主线程。然而,它们有很大的局限性