如何在 Android 中调用 Web 服务,使其即使在 Activity 处于后台时也能继续等待响应?

发布于 2024-12-06 11:08:06 字数 206 浏览 0 评论 0原文

如果我需要连接到 Web 服务并确保即使在屏幕旋转、电话突然弹出或 Activity 已置于后台后仍能继续下载,我必须采取什么方法?

我从这里的一些答案中读到,您可以使用 AsyncTask 或 Service 来连接到 Web 服务。连接到 Web 服务时这真的是正确的方法吗?比较建议的做法和常用的做法是什么?如果您还可以给我一些关于您建议的方法的解释和示例代码,我将不胜感激。

What approach do I have to take if I need to connect to a web service and make sure it will continue downloading even after the screen has been rotated or a phone call suddenly pops up or the activity has been put on the background?

I've read from some of the answers here that it is either you use AsyncTask or a Service to connect to the web service. Is it really the proper approach when connecting to web service? What is the more suggested approach and the commonly used approach? I'll appreciate it if you could also give me some explanation and sample codes regarding the approach that you will be suggesting.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦回旧景 2024-12-13 11:08:06

这实际上取决于您的要求:

服务
如果您的请求需要很长时间才能完成,并且您的应用程序在很大程度上取决于结果(持久数据),我建议使用服务,因为 android 系统可以决定杀死被推送到后台的应用程序,并且您的请求将就这么消失了。

异步任务
对于应用程序仅需要当前状态的数据的小请求(在实际应用程序关闭后可以丢弃的数据),我将使用 AsyncTask。当方向发生变化时,这可能会变得非常棘手,因此我提供了一个示例(注意 - 这是获得想法的蓝图,而不是最终的解决方案)。

我的应用程序和 AsyncTask 何时被终止?
当您将应用程序推送到后台时,它仍然处于活动状态。如果您使用另一个应用程序并且需要更多内存,Android 系统可能会决定终止您的活动应用程序以释放所需的资源。从这一刻起,你的活动和任务就消失了。但任务仍有机会完成并将其结果保存在数据库或 SD 卡中。

public class YourActivity extends Activity {

    private MyReqeustTask mRequestTask;

    public void onCreate(Bundle state) {
         // your activity setup

         // get your running task after orientation change
         mRequestTask = (MyRequestTask) getLastNonConfigurationInstance();

         if (mRequestTask != null) {
             mRequestTask.mActivity = new WeakReference<MyActivity>(this);
             processRequest();
         }
    }

    // call that somewhere - decide what implementation pattern you choose
    // if you need more than a single request - be inventive ;-)
    public startRequest() {
        mRequestTask = new MyRequestTask();
        mRequestTask.mActivity = new WeakReference<MyActivity>(this);
        mRequestTaks.execute(your, params);
    }

    // this is a request to process the result form your actual request
    // if it's still running, nothing happens
    public processResult() {
        if (mRequestTask == null || mRequest.getStatus() != Status.FINISHED) {
            return;
        }

        Result result = mRequest.getResult();
        // update and set whatever you want here
        mRequestTask = null;
    }

    public Object onRetainNonConfigurationInstance() {
        // retain task to get it back after orientation change
        return mRequestTask;
    }

    private static MyRequestTaks extends AsyncTask<Params, Progress, Result> {

        WeakReference<MyActivity> mActivity;

        protected Result doInBackground(Params... params) {
            // do your request here
            // don't ever youe mActivity in here, publish updates instead!
            // return your final result at the end
        }

        protected void onProgressUpdate(Progress... progress) {
            MyActivity activity = mActivity.get();

            if (activity != null) {
                // do whatever your want to inform activity about undates
            }
        }

        protected void onPostExecute(Result result) {
            MyActivity activity = mActivity.get();

            if (activity != null) {
                // this will update your activity even if it is paused
                activity.processRequest();
            }
        }
    }
}

It really depends on your requirements:

Service
If your request is taking a long time to finish and your application is heavily depending on the result (persistent data) I would suggest to use a service because the android system can decide to kill an application which was pushed to the background and your request will be simply gone.

AsyncTask
For small requests with data which your application is only needing for a current state (data which can pe thrown away after real application close) I would use a AsyncTask. This could get really tricky to handle when orientation changes occur so I provide an example (note - it's a blueprint to get the idea, not a final solution).

When is my Application and my AsyncTask getting killed?
When you push your application to the background it will be still active. If you use antoher application and this request more memory, the android system can dicide to kill your active application to free needed resources. From this moment your activity and your task is gone. But there is still a chance for the task to finish and persit it's results in a database or on the SD card.

public class YourActivity extends Activity {

    private MyReqeustTask mRequestTask;

    public void onCreate(Bundle state) {
         // your activity setup

         // get your running task after orientation change
         mRequestTask = (MyRequestTask) getLastNonConfigurationInstance();

         if (mRequestTask != null) {
             mRequestTask.mActivity = new WeakReference<MyActivity>(this);
             processRequest();
         }
    }

    // call that somewhere - decide what implementation pattern you choose
    // if you need more than a single request - be inventive ;-)
    public startRequest() {
        mRequestTask = new MyRequestTask();
        mRequestTask.mActivity = new WeakReference<MyActivity>(this);
        mRequestTaks.execute(your, params);
    }

    // this is a request to process the result form your actual request
    // if it's still running, nothing happens
    public processResult() {
        if (mRequestTask == null || mRequest.getStatus() != Status.FINISHED) {
            return;
        }

        Result result = mRequest.getResult();
        // update and set whatever you want here
        mRequestTask = null;
    }

    public Object onRetainNonConfigurationInstance() {
        // retain task to get it back after orientation change
        return mRequestTask;
    }

    private static MyRequestTaks extends AsyncTask<Params, Progress, Result> {

        WeakReference<MyActivity> mActivity;

        protected Result doInBackground(Params... params) {
            // do your request here
            // don't ever youe mActivity in here, publish updates instead!
            // return your final result at the end
        }

        protected void onProgressUpdate(Progress... progress) {
            MyActivity activity = mActivity.get();

            if (activity != null) {
                // do whatever your want to inform activity about undates
            }
        }

        protected void onPostExecute(Result result) {
            MyActivity activity = mActivity.get();

            if (activity != null) {
                // this will update your activity even if it is paused
                activity.processRequest();
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文