活动已泄露窗口,Dialog

时间:2016-03-11 14:17:52

标签: android android-activity dialog

我有一个具有设备列表的activityA,当我点击此列表中的某个项目时,会调用另一个活动(activityB)。

activityB是一个tabActivity,并使用viewPager来显示不同的片段。该活动有一个MenuItem来检查设备。单击MenuItem时,会出现一个对话框。但我创建了另一个类来显示Dialog,因为我希望这个Dialog显示在不同的片段中。

问题是,对话框出现但活动泄漏,并完成。

怎么办?

ActivityB:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tab_activity);

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    equipment = (Equipment) getIntent().getExtras().getSerializable("equipment");

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    viewPager.addOnPageChangeListener(this);
    setupViewPager(viewPager);


    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);

    tag = "FragA";
}


private void setupViewPager(ViewPager viewPager) {
    Bundle bundle = new Bundle();
    bundle.putSerializable("equipment", equipment);

    FragmentA fragmentA = new FragmentA();
    fragmentA.setArguments(bundle);

    FragmentB fragmentB = new FragmentB();
    fragmentB.setArguments(bundle);

    FragmentC fragmentC = new FragmentC();
    fragmentC.setArguments(bundle);

    adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(fragmentA, "FragA");
    adapter.addFragment(fragmentB, "FragB");
    adapter.addFragment(fragmentC, "FragC");
    viewPager.setAdapter(adapter);

}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
    index = viewPager.getCurrentItem();
    if (index == 0) {
        tag = "FragA";
    } else if (index == 1) {
        tag = "FragB";
    } else {
        tag = "FragC";
    }
    invalidateOptionsMenu();
}

@Override
public void onPageScrollStateChanged(int state) {

}

public void onBackPressed() {
    finish();
}

@Override
public void finishCheckEquipment(Boolean success) {
    Intent intent = new Intent(this, MainActivity.class);
    startActivity(intent);
}

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    switch (index) {
        case 0:
            FragmentA fragmentA = new FragmentA() adapter.getItem(index);
            if (fragmentA != null) {
                fragmentA.refreshFragmentA(newText);
                return false;
            }
        case 1:
            FragmentB fragmentB = new FragmentB() adapter.getItem(index);
            if (fragmentB != null) {
                fragmentB.refreshFragmentB(newText);
                return false;
 }
    }
    return false;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.alarm, menu);
    mCheckedItem = menu.findItem(R.id.action_check_equipment_final);
    mBackupSettings = menu.findItem(R.id.enable_backup_final);
    MenuItem searchItem = menu.findItem(R.id.menu_item_search_alarm);
    mSearchItem = searchItem;
    mSearchView = (SearchView) MenuItemCompat.getActionView(mSearchItem);
    mSearchView.setOnQueryTextListener(this);
    FragmentC fragmentC = (FragmentC) adapter.getItem(2);
    if (fragmentC != null && fragmentC.isVisible() && index == 2) {
        String backup = equipmentInfoFragment.verifyBackup();
        switch (backup) {
            case "enable":
                mBackupSettings.setTitle(getResources().getString(R.string.disable_backup));
                break;
            case "disable":
                mBackupSettings.setTitle(getResources().getString(R.string.enable_backup));
                break;
            case "null":
                break;
        }
    }

    switch (index) {
        case 0:
            mSearchItem.setVisible(true);
            mCheckedItem.setVisible(true);
            mBackupSettings.setVisible(false);
            return true;
        case 1:
            mSearchItem.setVisible(true);
            mCheckedItem.setVisible(true);
            mBackupSettings.setVisible(false);
            return true;
        case 2:
            mSearchItem.setVisible(false);
            mCheckedItem.setVisible(true);
            mBackupSettings.setVisible(true);
            return true;
        default:
            return super.onCreateOptionsMenu(menu);
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_check_equipment_final:
            CheckEquipment checkEquipment = new CheckEquipment(this);
            checkEquipment.StarCheckEquipment(TabActivity.this, equipment);
        case android.R.id.home:
            finish();
            return true;
        case R.id.enable_backup_final:
            EquipmentInfoFragment equipmentInfoFragment = (EquipmentInfoFragment) adapter.getItem(2);
            equipmentInfoFragment.startEnableBackup();

    }
    return super.onOptionsItemSelected(item);
}
}

具有对话框的类:

public class CheckEquipment extends FragmentActivity{

private OnCheckEquipmentListener listener;
private Equipment mEquipment;
private Context mContext;
private Boolean success;
private SharedPreferences sessionUserSettings = null;
Bundle bundle = new Bundle();

public CheckEquipment (OnCheckEquipmentListener listener) {
    this.listener = listener;
}

public void StarCheckEquipment(Context context, Equipment equipment) {
    this.mEquipment = equipment;
    this.mContext = context;
    EquipmentDialogInner equipmentFragment = new EquipmentDialogInner(mContext);
    equipmentFragment.setCancelable(false);
    equipmentFragment.show();
}

private String generateAuthHeaderValue(String login, String password) {
    String authorizationString = "Basic "
            + Base64.encodeToString((login + ":"
            + password).getBytes(), Base64.DEFAULT);

    authorizationString = authorizationString.replaceAll("\\n", "");
    return authorizationString;
}

private class EquipmentDialogInner extends Dialog implements View.OnClickListener {

    private Button cancel, send;

    public EquipmentDialogInner(Context context) {
        super(context);
    }

    @Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.dialog_alert_message);
    cancel = (Button) findViewById(R.id.cancel_button);
    send = (Button) findViewById(R.id.send_button);
    cancel.setOnClickListener(this);
    send.setOnClickListener(this);
 }

@Override
public void onClick(View view) {
    switch (view.getId()){
        case R.id.cancel_button:
            this.dismiss();
            break;
        case R.id.send_button:
            if (!Utils.isNetworkAvailable(mContext)){
                ActivityAction.showButtonToast(getOwnerActivity(), R.string.no_internet);
                return;
            }
            try {
                new TaskSendEquipmentDetail().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            } catch (Exception e) {
                e.printStackTrace();
            }
            this.dismiss();
            break;
        default:
    }
}
}

private class TaskSendEquipmentDetail extends AsyncTask<Void, Void, Boolean> {

    List<Equipment> mEquipmentSelected = new ArrayList<>();

    @Override
    protected Boolean doInBackground(Void... params) {
        mEquipmentSelected.add(mEquipment);
        success = false;
        sessionUserSettings = mContext.getSharedPreferences(Constants.SHARED_PREFERENCE_USER, 0);
        String url = Constants.PROVIDER_DOMAIN_URL + Constants.REQUEST_EQUIPMENT;
        String login = sessionUserSettings.getString(Constants.SHARED_PREFERENCE_USER_LOGIN, "");
        String password = sessionUserSettings.getString(Constants.SHARED_PREFERENCE_USER_PWD, "");

        try{
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            final GsonBuilder builder = new GsonBuilder();
            builder.excludeFieldsWithoutExposeAnnotation();
            final Gson gson = builder.create();

            String json = gson.toJson(mEquipmentSelected);
            StringEntity enity = new StringEntity(json);
            httpPost.setEntity(enity);
            httpPost.setHeader("Content-type", "application/json");
            httpPost.addHeader("Authorization", generateAuthHeaderValue(login, password));
            HttpResponse httpResponse = httpClient.execute(httpPost);

            int responseCode = httpResponse.getStatusLine().getStatusCode();

            switch (responseCode) {
                case 200:
                    success = true;
                    break;
                default:
                    System.out.print("erro");
            }
        }catch (Exception ignored){
            System.out.print(ignored);
        }

        return success;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        if (success) {
            if (listener != null){
                listener.finishCheckEquipment(success);
            }
        } else {
            Toast toast = Toast.makeText(mContext, "Não Foi Possível", Toast.LENGTH_SHORT);
            toast.show();
        }

    }
}

public interface OnCheckEquipmentListener {
    void finishCheckEquipment(Boolean success);
}

}

日志:

 03-11 10:37:16.809 29718-29718/com.company.provider E/WindowManager: android.view.WindowLeaked: Activity com.company.provider.controllers.equipmentDetail.TabActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView{7c1f044 V.E...... R.....I. 0,0-482,219} that was originally added here
                                                                       at android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)
                                                                       at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)
                                                                       at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:86)
                                                                       at android.app.Dialog.show(Dialog.java:319)
                                                                       at com.company.provider.controllers.equipmentDetail.CheckEquipment.StarCheckEquipment(CheckEquipment.java:52)
                                                                       at com.company.provider.controllers.equipmentDetail.TabActivity.onOptionsItemSelected(TabActivity.java:224)

1 个答案:

答案 0 :(得分:0)

我认为你应该从EquipmentDialogInner中取出CheckEquipment并将其作为一个类本身(新文件等),而不是将其作为CheckEquipment中的内部类。

然后,您可以更改onOptionsItemSelected,如下所示:

switch (item.getItemId()) {
    case R.id.action_check_equipment_final:
        EquipmentDialogInner dialog = new EquipmentDialogInner(this);
        dialog.setCancelable(false);
        dialog.show();
     case android.R.id.home:
        finish();
        return true;
     case R.id.enable_backup_final:
        EquipmentInfoFragment equipmentInfoFragment = (EquipmentInfoFragment) adapter.getItem(2);
        equipmentInfoFragment.startEnableBackup();

}