匿名实现导致内存泄漏

时间:2016-08-30 10:34:20

标签: java android memory-management memory-leaks leakcanary

即时通讯使用泄漏金丝雀来检测内存泄漏,我必须说它是非常好的库,以检测下面的潜在内存泄漏是由它产生的泄漏报告。我无法找到如何删除此匿名实现。

GoProFragment已泄露:

  
      
  • GC ROOT java.util.Timer $ TimerImpl。
  •   
  • 引用MainActivity $ 5.this $ 0(java.util.TimerTask的匿名子类)
  •   
  • 引用MainActivity.mHelper
  •   
  • 引用IabHelper.mPurchaseListener
  •   
  • 引用GoProFragment $ 2.this $ 0(IabHelper $ OnIabPurchaseFinishedListener的匿名实现)
  •   
  • GoProFragment实例
  •   
**GoProFragment.java**
public class GoProFragment extends BaseFragment {

    @Bind(R.id.btn_subscription_yearly)
    Button btnsubScriptionYearly;
    @Bind(R.id.btn_subscription_monthly)
    Button monthly;
    private ProgressDialog progressDialog;
    String product_price_one, product_price_two, product_price_three;
    @Bind(R.id.subscription_type)
    TextView subScriptionType;
    @Bind(R.id.graph_paid_feature)
    ImageView imageView;
    Bitmap icon;


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.pro_layout, container, false);
        ButterKnife.bind(this, view);
        setHasOptionsMenu(true);
        activity.preferences.setDisplayUpgrade(false);
        icon = BitmapFactory.decodeResource(activity.getResources(), R.drawable.subscription_img_two);
        imageView.setImageBitmap(icon);
        subScriptionType.setText(activity.preferences.getSubscriptionType());
        String[] sku = { Util.SKU_CHALLENGE,  Util.SKU_SUBSCRIPTION,  Util.SKU_YEAR_SUBSCRIPTION};
        if(isNetworkAvailable(activity)) {
            activity.mHelper.queryInventoryAsync(true, Arrays.asList(sku), mGotInventoryListener);
            showProgressDialog();
        }
        if (activity.preferences.isHasSubscription()) {
            /*btnsubScriptionYearly.setVisibility(View.GONE);
            monthly.setVisibility(View.GONE);*/
        }
        return view;
    }
    IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        @Override
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            dismissProgressDialog();
            product_price_one = inventory.getSkuDetails( Util.SKU_SUBSCRIPTION).getPrice();
            product_price_two = inventory.getSkuDetails( Util.SKU_YEAR_SUBSCRIPTION).getPrice();
            product_price_three = inventory.getSkuDetails( Util.SKU_CHALLENGE).getPrice();
            monthly.setVisibility(View.VISIBLE);
            btnsubScriptionYearly.setVisibility(View.VISIBLE);
            monthly.setText(activity.getString(R.string.monthly_subscription_text, product_price_one));
            btnsubScriptionYearly.setText(activity.getString(R.string.yearly_subscription_text, product_price_two));

        }

    };

    @OnClick(R.id.btn_subscription_monthly)
    public void onSubscription() {
        if (Validator.isNotNull(activity.mHelper)) {
            if (!activity.mHelper.subscriptionsSupported()) {
                 Util.showToast(activity, getString(R.string.subscription_not_supported));
                return;
            }
            if (!activity.mHelper.getAsyncInProgress()) {
                activity.mHelper.launchPurchaseFlow(activity,
                         Util.SKU_SUBSCRIPTION, IabHelper.ITEM_TYPE_SUBS,
                         Util.RC_REQUEST, mPurchaseFinishedListener,  Util.PAYLOAD);
            }
        }
    }

    @OnClick(R.id.btn_subscription_yearly)
    public void onYearSubscription() {
        if (Validator.isNotNull(activity.mHelper)) {
            if (!activity.mHelper.subscriptionsSupported()) {
                 Util.showToast(activity, getString(R.string.subscription_not_supported));
                return;
            }
            if (!activity.mHelper.getAsyncInProgress()) {
                activity.mHelper.launchPurchaseFlow(activity,
                         Util.SKU_YEAR_SUBSCRIPTION, IabHelper.ITEM_TYPE_SUBS,
                         Util.RC_REQUEST, mPurchaseFinishedListener,  Util.PAYLOAD);
            }
        }
    }

    private boolean isNetworkAvailable(Context context) {
        final ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null)
                for (int i = 0; i < info.length; i++)
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
        }

        return false;
    }
    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {

            // if we were disposed of in the meantime, quit.
            if (activity.mHelper == null) {
                return;
            }

            if (result.isFailure()) {
                return;
            }
            if (! Util.verifyDeveloperPayload(purchase)) {
                return;
            }
            if (purchase.getSku().equals( Util.SKU_SUBSCRIPTION)) {
                // bought the infinite gas subscription
                setPremium(purchase, Calendar.MONTH);
            } else if (purchase.getSku().equals( Util.SKU_YEAR_SUBSCRIPTION)) {
                // bought the infinite gas subscription
                setPremium(purchase, Calendar.YEAR);
            }
        }
    };
    public void setPremium(Purchase purchase, int duration) {
        if ( Util.verifyDeveloperPayload(purchase)) {
            activity.preferences.setHasSubscription(true);
            if (Validator.isNotNull(activity.adView)) {
                activity.adView.setVisibility(View.GONE);
            }
             Util.showToast(activity, getString(R.string.upgraded_successfully));
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date(purchase.getPurchaseTime()));
            calendar.add(duration, 1);
            activity.preferences.getUserInfo().setSubscriptionEndOn(calendar.getTime());
            if(purchase.getSku().equals( Util.SKU_SUBSCRIPTION))
            {
                activity.preferences.setSubscriptionType(activity.getResources().getString(R.string.monthly));
            }
            else {
                activity.preferences.setSubscriptionType(activity.getResources().getString(R.string.yearly));
            }
            activity.preferences.getUserInfo().setPremium(true);
            //subscriptionEndOn.setText(dateFormat.format(activity.preferences.getUserInfo().getSubscriptionEndOn()));
        }
    }

    private void showProgressDialog() {
        if (!activity.isFinishing() && progressDialog == null) {
            progressDialog = new ProgressDialog(activity,R.style.CustomProgressDialog);
            progressDialog.setCancelable(false);
            progressDialog.show();

        }

    }

    /**
     * dismiss Progress Dialog.
     */
    private void dismissProgressDialog() {
        if (!activity.isFinishing() && progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
            progressDialog=null;
        }
    }

    @Override
    public void onDetach() {
        if(Validator.isNotNull(icon)){
            icon.recycle();
        }
        super.onDetach();
    }

1 个答案:

答案 0 :(得分:2)

我不认为这是一个问题。你可以在片段中保持状态,但是你应该在setRetainInstance(true);回调中拨打onCreate

请参阅this article

或者,您可以在mGotInventoryListener = null;回调中设置字段onDetach