AsyncTask中的应用内结算查询库存?

时间:2013-08-24 01:37:28

标签: android asynchronous android-asynctask in-app-billing

我跟着this tutorial在我的app的启动时添加了一个加载屏幕,同时数据加载了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"));
        }
    }
};

1 个答案:

答案 0 :(得分:3)

AsyncTask非常有用,可以帮助您将长时间运行的作业放到后台线程上,并为您提供一个很好的清理机制,用于在后台任务运行之前,期间和之后更新UI ...所有没有直接搞乱线程。

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

在这种情况下,IabHelper methods you're using are asynchronous,它们将允许您从主线程启动它们,而不会阻止UI。

因此,无需在您用于其他工作的同一AsyncTask#doInBackground()方法中运行它们,只需将工作从主线程中删除。


我看到两个选项:

1)并发加载/ IAB请求

理想情况下,如果您需要在启动时加载一些数据(并且正在使用AsyncTask),您可以同时启动应用内结算请求。

您描述了主要活动,因此我假设您的应用以某种启动活动开头(?)。在该启动活动中,您可以使用:

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()

注释

一般情况下,我建议您不要推迟启动应用以检查优质升级。理想情况下,您会找到一种聪明的方法来保存此状态(购买的溢价)一次,然后避免将来的检查。您的用户会很感激。

但是,我不知道你的应用程序的免费/溢价之间的区别是什么,以及这种差异是否会立即出现......所以,这可能是你无法避免的。