RunonUiThread()或CustomListAdapter导致内存泄漏?

时间:2011-05-18 14:30:21

标签: android memory-leaks

我不确定是哪个导致内存泄漏所以根据logCat我打印了我的代码,请帮我解决我在这里做的错误?

public  class EfficientAdapter extends BaseAdapter {
        private LayoutInflater mInflater;
       // private Context context;
        ArrayList<String> data;
        int pos;

        public EfficientAdapter(Context context,ArrayList<String> received) {

          mInflater = LayoutInflater.from(context);
          //this.context = context;
          data = received;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
          ViewHolder holder;

          if(convertView == null)
          {
            convertView = mInflater.inflate(R.layout.list_cities, null);

            holder = new ViewHolder();
            holder.textLine = (TextView) convertView.findViewById(R.id.lblCity);

            convertView.setTag(holder);

          }else
          {
              holder = (ViewHolder)convertView.getTag();

          }

          convertView.setOnClickListener(new  android.view.View.OnClickListener() {

            @Override
            public void onClick(View v) {
                myInterface.search(getItem(position));
                SearchCity.this.dismiss();
            }
        });



          holder.textLine.setText(getItem(position));
          return convertView;
        }

        class ViewHolder {
          TextView textLine;

        }



        @Override
        public long getItemId(int position) {
            return 0;
        }

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

        @Override
        public String getItem(int position) {
          return data.get(position);
        }



      }

堆栈跟踪:

05-18 19:08:57.682: ERROR/WindowManager(314): Activity com.FindMe.DisplayAtms has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@4501cdf0 that was originally added here
05-18 19:08:57.682: ERROR/WindowManager(314): android.view.WindowLeaked: Activity com.FindMe.DisplayAtms has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@4501cdf0 that was originally added here
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.view.ViewRoot.<init>(ViewRoot.java:247)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.app.Dialog.show(Dialog.java:241)
05-18 19:08:57.682: ERROR/WindowManager(314):     at com.FindMe.DisplayAtms$1.run(DisplayAtms.java:269)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.app.Activity.runOnUiThread(Activity.java:3707)
05-18 19:08:57.682: ERROR/WindowManager(314):     at com.FindMe.DisplayAtms$AsycLoaderFromDbAndMapInjector.onPreExecute(DisplayAtms.java:880)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.os.AsyncTask.execute(AsyncTask.java:391)
05-18 19:08:57.682: ERROR/WindowManager(314):     at com.FindMe.DisplayAtms.LoadFunction(DisplayAtms.java:145)
05-18 19:08:57.682: ERROR/WindowManager(314):     at com.FindMe.DisplayAtms$7.search(DisplayAtms.java:513)
05-18 19:08:57.682: ERROR/WindowManager(314):     at com.FindMe.SearchCity$EfficientAdapter$1.onClick(SearchCity.java:152)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.view.View.performClick(View.java:2408)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.view.View$PerformClick.run(View.java:8816)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.os.Handler.handleCallback(Handler.java:587)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.os.Handler.dispatchMessage(Handler.java:92)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.os.Looper.loop(Looper.java:123)
05-18 19:08:57.682: ERROR/WindowManager(314):     at android.app.ActivityThread.main(ActivityThread.java:4627)
05-18 19:08:57.682: ERROR/WindowManager(314):     at java.lang.reflect.Method.invokeNative(Native Method)
05-18 19:08:57.682: ERROR/WindowManager(314):     at java.lang.reflect.Method.invoke(Method.java:521)
05-18 19:08:57.682: ERROR/WindowManager(314):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
05-18 19:08:57.682: ERROR/WindowManager(314):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
05-18 19:08:57.682: ERROR/WindowManager(314):     at dalvik.system.NativeStart.main(Native Method)

的AsyncTask:

public class Asyctast extends AsyncTask<Void, Object, Void>
{

 private ProgressDialog dialog = new ProgressDialog(DisplayAtms.this);

   @Override
    protected void onPreExecute() {
        super.onPreExecute();
        runOnUiThread(showProgress);
    }


   @Override
    protected void onProgressUpdate(final Object... args) {
        super.onProgressUpdate(args);
        if ((Boolean) args[0]) {
            Toast.makeText(DisplayAtms.this, args[1].toString(),
                    Toast.LENGTH_LONG).show();
        }
    }

   @Override
    protected Void doInBackground(Void... arg0) {
         Log.d("Asynctask", ""+arg0);  


            publishProgress(true,"sd sdfsdf");


            return null;

    }

@Override
protected void onPostExecute(Boolean result) {
    runOnUiThread(hideProgress);
    }

}


Runnable showProgress = new Runnable() {

        @Override
        public void run() {
            pd = new ProgressDialog(DisplayAtms.this);
            pd = registerDialog(pd);
            pd.show();
        }
};  


Runnable hideProgress = new Runnable() {

        @Override
        public void run() {
            if(pd != null)
            pd.hide();
        }
};

1 个答案:

答案 0 :(得分:0)

AsyncTask.onPostExecute在UI线程中运行,不需要类似的东西:

Runnable showProgress = new Runnable() {

    @Override
    public void run() {
        pd = new ProgressDialog(DisplayAtms.this); //here is the leak
        pd = registerDialog(pd);
        pd.show();

    }
};  

试试这个:

@Override
protected void onPreExecute() {
    pd.show();
}

@Override 
protected void onPostExecute(Boolean result) {
    pd.dismiss();
}

您也可以使用Handler
Here is tutorial for handler