Android 加载时的多个 Web 服务调用

发布于 2024-10-20 19:29:43 字数 2934 浏览 2 评论 0原文

我学习Android已经有3个月左右的时间了。不过,我还没有遇到过这样的事情。

我想在应用程序首次加载时访问多个不同的 Web 服务。来自这些 Web 服务的响应应进入数据库,以便在应用程序需要时进行检索。我有一个启动屏幕,我正在尝试执行此操作:

public class SplashScreen extends BaseActivity {

    protected static final int SPLASH_DURATION = 2000;

    protected ContactInfoRetriever contactInfoRetriever = new ContactInfoRetriever();

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash_screen);
    startSplashThread();
    }

    private void startSplashThread() {
    Thread splashThread = new Thread() {
        @Override
            public void run() {
            try {
            Looper.prepare();
            // fire off the calls to the different web services.
            updateContactInfo();
            updateFooInfo();
            updateBarInfo();

            int waited = 0;
            while (waited < SPLASH_DURATION) {
                sleep(100);
                waited += 100;
            }                   
            }
            catch (InterruptedException e) {
            Log.e(SplashScreen.class.getSimpleName(), "The splash thread was interrupted.");
            }
            finally {
            finish();
            startActivity(new Intent(SplashScreen.this, LandingPageActivity.class));
            }
        }

        };
    splashThread.start();
    }

    protected void updateContactInfo() {

    PerformContactInfoSearchTask task = new PerformContactInfoSearchTask();
    task.execute();
    }    

    protected void updateFooInfo() {
    PerformFooTask task = new PerformFooTask();
    task.execute();
    }

    protected void updateBarInfo() {
    PerformBarTask task = new PerformBarTask();
    task.execute();
    }

    private class PerformContactInfoSearchTask extends AsyncTask<String, Void, ContactInfo> {


    @Override
        protected ContactInfo doInBackground(String... params) {
        // this calls a class which calls a web service, and is then passed to an XML parser.
        // the result is a ContactInfo object
        return contactInfoRetriever.retrieve();
    }

    @Override
        protected void onPostExecute(final ContactInfo result) {
        runOnUiThread(new Runnable() {

            public void run() {
            InsuranceDB db = new InsuranceDB(SplashScreen.this);
            // insert the ContactInfo into the DB
            db.insertContactInfo(result);
            }
        });
    }

    }   

    private class PerformFooTask extends AsyncTask<String, Void, FooInfo> {
    // similar to the PerformContactInfoSearchTask
    }

    private class PerformBarTask extends AsyncTask<String, Void, BarInfo> {
    // similar to the PerformContactInfoSearchTask
    }

}

我尚未成功完成此操作。最好的方法是什么?任务完成后我不需要更新 UI 线程。这是否意味着我应该使用 AsyncTask 以外的其他东西?我读过一些关于 Looper 和 Handler 的内容。这是正确的使用方式吗?任何代码示例都会很棒。

谢谢, 扎克

I have been learning Android for the past 3 months or so. However, I haven't come across anything like this yet.

I want to access several different web services when the application is initially loaded. The response from these web services should go into the DB for retrieval where needed in the application. I have a splash screen from which I am attempting to do this:

public class SplashScreen extends BaseActivity {

    protected static final int SPLASH_DURATION = 2000;

    protected ContactInfoRetriever contactInfoRetriever = new ContactInfoRetriever();

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.splash_screen);
    startSplashThread();
    }

    private void startSplashThread() {
    Thread splashThread = new Thread() {
        @Override
            public void run() {
            try {
            Looper.prepare();
            // fire off the calls to the different web services.
            updateContactInfo();
            updateFooInfo();
            updateBarInfo();

            int waited = 0;
            while (waited < SPLASH_DURATION) {
                sleep(100);
                waited += 100;
            }                   
            }
            catch (InterruptedException e) {
            Log.e(SplashScreen.class.getSimpleName(), "The splash thread was interrupted.");
            }
            finally {
            finish();
            startActivity(new Intent(SplashScreen.this, LandingPageActivity.class));
            }
        }

        };
    splashThread.start();
    }

    protected void updateContactInfo() {

    PerformContactInfoSearchTask task = new PerformContactInfoSearchTask();
    task.execute();
    }    

    protected void updateFooInfo() {
    PerformFooTask task = new PerformFooTask();
    task.execute();
    }

    protected void updateBarInfo() {
    PerformBarTask task = new PerformBarTask();
    task.execute();
    }

    private class PerformContactInfoSearchTask extends AsyncTask<String, Void, ContactInfo> {


    @Override
        protected ContactInfo doInBackground(String... params) {
        // this calls a class which calls a web service, and is then passed to an XML parser.
        // the result is a ContactInfo object
        return contactInfoRetriever.retrieve();
    }

    @Override
        protected void onPostExecute(final ContactInfo result) {
        runOnUiThread(new Runnable() {

            public void run() {
            InsuranceDB db = new InsuranceDB(SplashScreen.this);
            // insert the ContactInfo into the DB
            db.insertContactInfo(result);
            }
        });
    }

    }   

    private class PerformFooTask extends AsyncTask<String, Void, FooInfo> {
    // similar to the PerformContactInfoSearchTask
    }

    private class PerformBarTask extends AsyncTask<String, Void, BarInfo> {
    // similar to the PerformContactInfoSearchTask
    }

}

I haven't been successful with this yet. What is the best way to do this? I don't need to update the UI thread when the tasks are completed. Does this mean I should be using something other than AsyncTask? I read something about a Looper and Handler. Is this the correct thing to use? Any code samples would be wonderful.

Thanks,
Zack

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

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

发布评论

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

评论(1

痞味浪人 2024-10-27 19:29:43

您很可能会遇到竞争条件,因为在等待期结束且活动完成之前 Web 服务调用尚未完成。

更好的方法可能是:

  • 删除等待、finish() 和
    startActivity() 从启动画面
    线。
  • 结合所有网络服务
    调用 AsyncTask。
  • 将所有数据库操作移动到
    任务的 doInBackground 方法。
  • 在任务的 onPostExecuteMethod 中,执行
    你的完成和startActivity()。

More than likely you have a race condition in that the web service calls are not completed before the wait period has ended and the activity is finished.

A better approach may be to:

  • remove the waiting, finish(), and
    startActivity() from the splash
    thread.
  • combine all the web service
    calls into on AsyncTask.
  • move all the db operations to the
    task's doInBackground method.
  • in the task's onPostExecuteMethod, do
    your finish and startActivity().
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文