1

在使用 AsyncTask 的 doInBackground() 函数加载数据时,我按照本教程向我的应用程序的启动添加了加载屏幕。

我的应用程序还具有应用内计费高级升级功能,我想在发布时查询库存以检查此功能。但是,这些IabHelper功能已经是异步的。

如何将IabHelper检查集成到 doInBackground() 中,以便仅在一切成功完成后才加载主要活动?

我的计费代码如下:

private void checkForPremiumPurchase()
{
    billingHelper = new IabHelper(this, Constants.BASE_64_KEY);
    //Start setup. This is asynchronous and the specified listener will be called once setup completes.
    billingHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        public void onIabSetupFinished(IabResult result) {
            if(result.isSuccess()) {
                billingHelper.queryInventoryAsync(mGotInventoryListener);
            }
        }
    });
}

//Listener that's called when we finish querying the items and subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener()
{
    @Override
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        if(result.isSuccess()) {
            isPremium = inventory.hasPurchase(Constants.SKU_PREMIUM);
            Log.d(Constants.TAG, "App is " + (isPremium ? "PREMIUM" : "NOT PREMIUM"));
        }
    }
};
4

1 回答 1

3

AsyncTask非常有用,它可以帮助您将长时间运行的作业放到后台线程上,并为您提供一个很好的干净机制,用于在后台任务运行之前、期间和之后更新 UI……所有这些都不会直接与线程混淆。

然而,其他一些 Android API 设置为允许您在主 (UI) 线程上发起调用,然后在幕后,它们将在后台线程上完成它们的工作(它们甚至可以使用AsyncTask.不一定关心)。

在这种情况下,IabHelper 您使用的方法是异步的,它们将允许您从主线程启动它们,而不会阻塞 UI。

因此,没有必要以AsyncTask#doInBackground()您用于其他工作的相同方法运行它们,只是为了让工作脱离主线程。


我看到两个选项:

1) 并发加载/IAB 请求

理想情况下,如果您需要在启动时加载一些数据(并AsyncTask为此使用),您也可以同时启动您的 In-App Billing 请求。

您描述了一个主要活动,所以我假设您的应用程序以某种类型的启动活动开始(?)。在该启动活动中,您可以使用:

public void onCreate(Bundle savedInstanceState) {
    new MyLoadingAsyncTask().execute();

    checkForPremiumPurchase();
}

然后您将在 IAB 检查完成时启动主要活动:

public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
    isPremium = false;
    if(result.isSuccess()) {
        isPremium = inventory.hasPurchase(Constants.SKU_PREMIUM);
        Log.d(Constants.TAG, "App is " + (isPremium ? "PREMIUM" : "NOT PREMIUM"));
    }
    Intent i = new Intent(self, MainActivity.class);
    i.putExtra("IsPremium", isPremium);
    startActivity(i);
}

这假设网络 IAB 事务将比您的应用程序的正常“加载”过程花费更长的时间。(如果该假设无效,请发表评论,我会处理这种情况)

2) 序列化加载,然后是 IAB

如果您的应用程序设计有其他要求您“完成加载”然后启动 IAB 请求,那么您可以在完成工作checkForPremiumPurchase()时调用:AsyncTask

 protected void onPostExecute(Long result) {
     checkForPremiumPurchase();
 }

AsyncTask#onPostExecute()加载完成时在主线程上调用,并且checkForPremiumPurchase()在主线程上调用是安全的。

评论

一般来说,我建议您不要延迟启动您的应用程序以检查是否有高级升级。理想情况下,您会找到一种聪明的方法来保存此状态(已购买溢价)一次,然后避免将来的检查。您的用户会欣赏这一点。

但是,我不知道您的应用程序的免费/高级之间的区别是什么,以及这种区别是否立即显示出来......所以,也许这是您无法避免的事情。

于 2013-08-24T07:59:29.570 回答