2011-05-20 50 views
2

我有一个问题,当我使用json解析一个活动,然后第一次它在前面运行非常好,但第二次当我想运行相同的活动它返回窗口泄漏错误。这个问题的解决方案是什么?在android应用程序泄露的窗口

错误:

05-20 12:02:14.579: ERROR/WindowManager(321): Activity org.shopzilla.android.search.SearchResultActivity has leaked window [email protected] that was originally added here 
05-20 12:02:14.579: ERROR/WindowManager(321): android.view.WindowLeaked: Activity org.shopzilla.android.search.SearchResultActivity has leaked window [email protected] that was originally added here 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.view.ViewRoot.<init>(ViewRoot.java:247) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.view.Window$LocalWindowManager.addView(Window.java:424) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.Dialog.show(Dialog.java:241) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.ProgressDialog.show(ProgressDialog.java:107) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.ProgressDialog.show(ProgressDialog.java:90) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at org.shopzilla.android.search.SearchResultActivity.onCreate(SearchResultActivity.java:126) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.os.Handler.dispatchMessage(Handler.java:99) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.os.Looper.loop(Looper.java:123) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at java.lang.reflect.Method.invokeNative(Native Method) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at java.lang.reflect.Method.invoke(Method.java:521) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
05-20 12:02:14.579: ERROR/WindowManager(321):  at dalvik.system.NativeStart.main(Native Method) 

代码:

public class SearchGridActivity extends Activity{ 

    URL url1; 
    Bitmap bmp; 
    Bundle bundle; 
    GridView grid; 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.searchgrid); 

     grid = (GridView)findViewById(R.id.Search_Result_Grid); 

     final ProgressDialog dialog = ProgressDialog.show(this, "BIZRATE", "Loading.......", true); 
       final Handler handler = new Handler() { 

        public void handleMessage(Message msg) { 

         callHereForEff(); 
         dialog.dismiss(); 


         } 
        }; 
        Thread checkUpdate = new Thread() { 
        public void run() { 
         SearchResult_Json.json_parsing(); 
         handler.sendEmptyMessage(0); 

         } 
        }; 
       checkUpdate.start(); 



     bundle = getIntent().getExtras(); 
     EditText et_search_grid = (EditText)findViewById(R.id.txt_search_grid); 
     et_search_grid.setText(bundle.getString("keyword")); 

     Button btn_list = (Button)findViewById(R.id.btn_searchresult_list); 
     Button btn_refine = (Button)findViewById(R.id.btn_RefineSearch); 

     btn_refine.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // TODO Auto-generated method stub 
      Intent intent = new Intent(SearchGridActivity.this,SearchRefine.class); 
      startActivity(intent); 
      } 
     }); 

     btn_list.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // TODO Auto-generated method stub 
      Intent intent = new Intent(SearchGridActivity.this,SearchResultActivity.class); 
      intent.putExtra("keyword", bundle.getString("keyword")); 
      startActivity(intent); 
      } 
     }); 

    } 


    protected void callHereForEff() { 
     grid.setAdapter(new ImageAdapter(this));//Load the GridView 
    } 


    //Showing Images with TextViews in Grid View 
    public class ImageAdapter extends BaseAdapter{ 
      Context mContext; 
      public static final int ACTIVITY_CREATE = 10; 
      public ImageAdapter(Context c){ 
       mContext = c; 
      } 
      @Override 
      public int getCount() { 
       // TODO Auto-generated method stub 
       return 5; 
      } 

      @Override 
      public View getView(int position, View convertView, ViewGroup parent) { 
       // TODO Auto-generated method stub 
       View v; 
       try { 
        url1 = new URL(SearchResultActivity.image_me.get(position)); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

       try { 
        bmp = BitmapFactory.decodeStream(url1.openConnection().getInputStream()); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       if(convertView==null){ 
        LayoutInflater li = getLayoutInflater(); 
        v = li.inflate(R.layout.search_result_griditem, null); 
        TextView tv = (TextView)v.findViewById(R.id.txt_SearchResultGrid_Price); 
        tv.setText(SearchResultActivity.min_price.get(position)); 
        ImageView iv = (ImageView)v.findViewById(R.id.img_SearchResultGrid_Product); 
        iv.setImageBitmap(bmp); 

       } 
       else 
       { 
        v = convertView; 
       } 
       return v; 
      } 
      @Override 
      public Object getItem(int arg0) { 
       // TODO Auto-generated method stub 
       return null; 
      } 
      @Override 
      public long getItemId(int arg0) { 
       // TODO Auto-generated method stub 
       return 0; 
      } 
     } 

} 

回答

7

这里是有问题的模式,我认为您所遇到:

  • 您创建活动。
  • 您生成一个工作线程,该工作线程具有对该活动的引用。
  • 活动以某种方式关闭/完成(),最有可能是用户交互的结果,并且系统尝试收集其资源。
  • 然而,该工作线程仍在运行,并且其持有对活动的引用......因此该活动已“泄漏”,并且系统无法自由回收它,而没有以潜在危险方式更改/破坏您的应用程序状态。
    • 活动是Android中的重量级对象,并且(攻击性)系统资源管理器需要能够回收它们以确保为用户提供流畅且高性能的体验。所以这个'泄漏'被认为是一个错误。如果您泄漏引用时,系统会抱怨(而通常在 -

明白,Android的回收资源的咄咄逼人,自以为是的方式(特别是框架对象喜欢用正规的生命周期管理活动),这是非常重要的一个正常的jvm场景,这将是一个内存泄漏,你可能永远不会注意到)。

您需要检查您的工作线程(上面代码中的'checkUpdate')如何与其父代或产卵活动进行交互。特别是 - 当一个Activity被拆除(finish(),onStop等)时,很可能需要以某种方式取消或销毁该工作线程。