内存泄漏 - 多个活动实例

时间:2013-09-15 08:14:19

标签: android memory-leaks

我有几项活动。

该应用程序内存不足。我尝试gc.clean()在所有活动中(onDestroy),空引用,launchMode="singleTop"但没有任何成功。

在MAT中,我发现我有多个具有相同活动的对象,如果我没弄错的话,这是默认行为。

例如,在第一次启动时,我将进行主要活动,如果我退出并再次启动,我将有2个实例。

这会使VM增长,直到显示强制关闭对话框。

我的代码示例:

public class Splash extends Activity
   {
    private static Handler handler;
    private static Thread splashThread;
    private MyProgressDialog dialog;

    private Netroads netroads;

    private int debug;

    private AsyncTask<Void,Void,Void> mConnectionTask;
    private boolean checkInternetConnection = false;

    private SharedPreferences ref;
    private SharedPreferences.Editor ed;

    private boolean firstOperationKey = false;
    private boolean userPay = false;

    private String macAddress = "";

    private String answer = "";
    private String extra = "";
    private int status = Consts.STATUS_SERVER_BUSY;

    private String paymentType = "";
    private boolean paymentStatus = false;

    private String versionName = "";

    private RelativeLayout splash_layout;

    private RelativeLayout welcome_message_layout;

    private TextView welcome_message_text;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.splash_layout);

        getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

        netroads = ((Netroads)getApplicationContext());

        ref = getSharedPreferences("NETROADS",MODE_PRIVATE);
        ed = ref.edit();

        //ed.putString("userID","2");
        //ed.putBoolean("LOGOUT",false);
        //ed.commit();

        //change background by LANGUAGEMODENUMBER
        splash_layout = (RelativeLayout)findViewById(R.id.splash_layout);
        welcome_message_layout = (RelativeLayout)findViewById(R.id.welcome_message_layout);
        //welcome_message_layout = new RelativeLayout(getApplicationContext());
        welcome_message_text = (TextView)findViewById(R.id.welcome_message_text);
        //welcome_message_text = new TextView(getApplicationContext().);

        if(ref.getBoolean("LANGUAGEMODECHANGE",false))
        {        

            welcome_message_layout.setBackgroundResource(R.drawable.welcome_message);
            welcome_message_text.setText(getString(R.string.welcome));

            switch(ref.getInt("LANGUAGEMODENUMBER",Consts.DEFAULT))
            {
                case Consts.HEBREW:
                    splash_layout.setBackgroundResource(R.drawable.welcome_hebrew);
                    break;
                case Consts.ENGLISH:
                    splash_layout.setBackgroundResource(R.drawable.welcome_english);
                    break;
                case Consts.RUSSIAN:
                    splash_layout.setBackgroundResource(R.drawable.welcome_russian);
                    break;
                case Consts.ARABIC:
                    splash_layout.setBackgroundResource(R.drawable.welcome_arabic);
                    break; 
                default:
                    splash_layout.setBackgroundResource(R.drawable.bg);
                    break; 
            }//close switch
        }

        if(ref.getBoolean("LANGUAGEMODECHANGE",false))
        {
            ed.putBoolean("LANGUAGEMODECHANGE",false);
            ed.commit();
        }

        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        if(wifiManager.isWifiEnabled())
        {
            WifiInfo info = wifiManager.getConnectionInfo();
            macAddress = info.getMacAddress();
        } 
        else 
        {
            wifiManager.setWifiEnabled(true);

            WifiInfo info = wifiManager.getConnectionInfo();
            macAddress = info.getMacAddress();
            wifiManager.setWifiEnabled(false);
        }

        PackageInfo pinfo;
        try {
            pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
            versionName = pinfo.versionName;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }

        handler = new Handler();
        splashThread = (Thread) getLastNonConfigurationInstance();
        if (splashThread != null && splashThread.isAlive()) 
        {
            dialog = MyProgressDialog.show(this,"","");
        }

    }//close onCreate

    public void onResume()
    {
        super.onResume();

        debug = 0;
        if(debug == 1)
        {
            Intent intent = new Intent(Splash.this, Main.class); 
            startActivity(intent);
            Splash.this.finish();
        }
        else
        {
            dialog = MyProgressDialog.show(this,"","");

            if(netroads.checkGPS(Splash.this))
            {
                mConnectionTask = new AsyncTask<Void, Void, Void>()
                {
                    @Override
                    protected Void doInBackground(Void... params) 
                    {
                        for(int i=0;i<3;i++)
                        {
                            HttpGet requestForTest = new HttpGet("http://m.google.com");
                            try
                            {
                                new DefaultHttpClient().execute(requestForTest);
                                checkInternetConnection = true;
                            } 
                            catch (Exception e)
                            {
                                checkInternetConnection = false;
                            }
                        }
                        return null;
                    }

                    @Override
                    protected void onPostExecute(Void result)
                    {
                        dialog.dismiss();
                        mConnectionTask = null;
                        if(checkInternetConnection)
                        {
                            dialog = MyProgressDialog.show(Splash.this,"","");
                            startSplashThread();    
                        }
                        else
                        {
                            netroads.showRegularDialog(getString(R.string.connection_problem), getString(R.string.internet_connection_problem), getString(R.string.ok), Splash.this);
                        }
                    }
                };
                mConnectionTask.execute(null, null, null);
            }
            else
            {
                dialog.dismiss();
                netroads.showGPSAlert(Splash.this);
            }
        }       
    }//close onResume

    public void startSplashThread()
    {
        splashThread = new splashThread();
        splashThread.start();
    }//close splashThread

    // Save the thread
    @Override
    public Object onRetainNonConfigurationInstance() {
        return splashThread;
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();

        if (dialog != null) 
        {
            dialog.dismiss();
            dialog = null;
        }

        netroads.unbindDrawables(findViewById(R.id.splash_layout)); 
        System.gc();

    }//close onDestroy

    public class splashThread extends Thread 
    {   
        @Override
        public void run() 
        {
            try
            {
                if(ConnectionDetector.checkInternetConnection())
                {
                    if(ref.getString("userID","").equalsIgnoreCase("") || ref.getBoolean("LOGOUT",false))
                        firstOperationKey = true;  //first operation after download from google play
                    else
                    {
                        checkUserActive();
                        netroads.getUsersCount(Splash.this);
                    }
                    handler.post(new splashRunnable());
                }
            } 
            finally
            {
                splashThread.interrupt();
            }
        }

    }//close splashThread 

    public class splashRunnable implements Runnable
    {
        public void run() 
        {
            dialog.dismiss();
            if(firstOperationKey)
            {
                Intent intent = new Intent(Splash.this,AppDescription.class);
                startActivity(intent);
                finish();
            }
            else if(status == Consts.STATUS_OPERATION_SUCCESSFUL)
            {
                if(netroads.answerFromServerIsOK(answer))
                {
                    Intent intent = new Intent(Splash.this,Main.class);
                    startActivity(intent);
                    finish();
                }
                else
                {
                    Log.e(Consts.TAG,"STATUS = OK, ANSWER = -2 (CLEAR SESSION)");
                    clearSession();
                }       
            }
            else if(status == Consts.STATUS_USER_UNEXISTS)
            {
                clearSession();
            }
            else
            {
                netroads.answerFromServerIsOK(answer);
                netroads.serverException(Splash.this,status);
            }
        }
    }//close splashRunnable 

    public void clearSession()
    {
        ed.putBoolean("LOGOUT",true);
        ed.commit();

        startSplashThread();
    }//close clearSession

    public boolean checkUserActive()
    {
        Log.e(Consts.TAG,"checkUserActive()");

        String url = new String(Consts.SERVER + "checkUserActive");

        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(url);

        try 
        {           
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("userID",ref.getString("userID","")));
            nameValuePairs.add(new BasicNameValuePair("MAC",macAddress));

            httppost.addHeader("appPassword",Consts.APP_PASSWORD);

            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));

            HttpResponse response = httpclient.execute(httppost);
            HttpEntity httpEntity = response.getEntity();
            String xmlString = EntityUtils.toString(httpEntity);

            Log.d(Consts.TAG,xmlString);

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = factory.newDocumentBuilder();
            InputSource inStream = new InputSource();
            inStream.setCharacterStream(new StringReader(xmlString));
            Document doc = db.parse(inStream);  
            NodeList nodeList;
            boolean normalize = false;
            try
            {
                doc.getDocumentElement().normalize();
                nodeList = doc.getElementsByTagName("Client");
                normalize = true;
            }
            catch(Exception e)
            {
                nodeList = null;
            }

            if(normalize)
                if(nodeList.getLength() > 0)
                {
                    for(int i=0; i < nodeList.getLength(); i++)
                    {
                        Node node = nodeList.item(i);
                        Element firstElement = (Element) node;

                        try{
                        NodeList myNodeList = firstElement.getElementsByTagName("userID");
                        Element myElement = (Element)myNodeList.item(0);
                        myNodeList = myElement.getChildNodes();
                        Log.d(Consts.TAG,"checkUserActive - userID:"+myNodeList.item(0).getNodeValue());

                        myNodeList = firstElement.getElementsByTagName("status");
                        myElement = (Element)myNodeList.item(0);
                        myNodeList = myElement.getChildNodes();
                        status = Integer.parseInt(myNodeList.item(0).getNodeValue());

                        myNodeList = firstElement.getElementsByTagName("answer");
                        myElement = (Element)myNodeList.item(0);
                        myNodeList = myElement.getChildNodes();
                        answer = myNodeList.item(0).getNodeValue();

                        myNodeList = firstElement.getElementsByTagName("extra");
                        myElement = (Element)myNodeList.item(0);
                        myNodeList = myElement.getChildNodes();
                        extra = myNodeList.item(0).getNodeValue();
                        Netroads.paymentKey = extra;

                        }catch(Exception e){e.printStackTrace();}

                    }//close for
                    return true;
                }//close if

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

        return false;
    }//close checkUserActive    

    @Override
    protected void onActivityResult(int requestCode,int resultCode, Intent data) 
    {
        super.onActivityResult(requestCode, resultCode, data);
        //if user is google play, paypal,...
        if(resultCode == Consts.PAYMENT_STATUS_IAP)
        {
            Log.e(Consts.TAG,"onActivityResult() - Splash");

            try
            {
                paymentStatus = data.getExtras().getBoolean("paymentStatus");
            }
            catch(Exception e){paymentStatus = false;}

            if(paymentStatus)
            {
                paymentType = data.getExtras().getString("paymentType");
                netroads.startSetUser(Splash.this,paymentType,"1","2",macAddress,versionName,ref.getString("userID",""));//TODO Chane to auto function
            }
            else
            {
                netroads.showRegularDialog(getString(R.string.netroads_server),getString(R.string.user_cancel_purchase),getString(R.string.ok),Splash.this);
            }
        }

    }//close onActivityResult      




}//close Splash

泄漏在哪里?

修改

以下是照片: enter image description here

enter image description here

2 个答案:

答案 0 :(得分:-1)

是否可以与未发布上下文引用的WifiManager相关联? http://code.google.com/p/android/issues/detail?id=43945

答案 1 :(得分:-2)

我想你可能会以错误的方式看待它。

什么是撞车?它是否会导致splash_layout.setBackgroundResource(...)调用之一?

如果是,您的图像可能太大(它们的重量是多少?)。 如果是这种情况,您应该考虑调整图像大小,然后查看http://developer.android.com/training/displaying-bitmaps/load-bitmap.html