Alert This Handler class should be static or leaks might occur

0

I have the following code that works ok but Studio paints it to me as the image shows, I found several answers but I still do not understand what I have to do so that it does not come out painted anymore.

public class SplashActivity extends AppCompatActivity {

private ProgressBar progressBar;
static RingProgressBar ringProgressBar;
static int progress = 0;


Handler myHandler = new Handler(){
    public void handleMessage (Message msg){
        if(msg.what == 0){
            if(progress < 100){
                progress++;
                ringProgressBar.setProgress(progress);
            }
        }
    }
};

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

    ringProgressBar = (RingProgressBar) findViewById(R.id.progress_bar_1);

    new Thread(new Runnable() {
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                try{
                    Thread.sleep(40);
                    myHandler.sendEmptyMessage(0);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }).start();
 }
}

Corrected Code and without warning:

public class SplashActivity extends AppCompatActivity {


static RingProgressBar ringProgressBar;
static int progress = 0;

private static class MyHandler extends Handler {
    public void handleMessage(Message msg) {
        if (msg.what == 0) {
            if (progress < 100) {
                progress++;
                ringProgressBar.setProgress(progress);
            }
        }
    }
}

private final MyHandler myHandler = new MyHandler();

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

    ringProgressBar = findViewById(R.id.progress_bar_1);
    final Intent i = new Intent(this, MainActivity.class);

    ringProgressBar.setOnProgressListener(new RingProgressBar.OnProgressListener() {
        @Override
        public void progressToComplete() {
            Toast.makeText(SplashActivity.this, "Bienvenido!", Toast.LENGTH_SHORT).show();
            Thread timer = new Thread(){
                public void run(){
                    try{
                        sleep(2000);

                    }
                    catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    finally {
                        startActivity(i);
                        finish();
                    }
                }
            };
            timer.start();
        }
    });

    new Thread(new Runnable() {
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                try{
                    Thread.sleep(40);
                    myHandler.sendEmptyMessage(0);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }).start();
   }
 }
    
asked by Juan 09.10.2018 в 01:13
source

1 answer

2

What is happening is that you are reading memory. This happens because the handler instantiated in that way is an anonymous class that belongs to the SplashActivity class, therefore it has a reference to the SplashActivity. And in turn the SplashActivity has a reference to the handler.

The Garbage Collector can not eliminate the handler or the splash because they always reference each other and hence the warning.

To avoid the memory leak problem you should create the class of the handler as a private static class and pass the reference to the Activity as a weak reference.

private static class MyHandler extends Handler {
   private final WeakReference<SplashActivity> mActivity;

   public MyHandler(SplashActivity activity) {
      mActivity = new WeakReference<SampleActivity>(activity);
   }

   @Override
   public void handleMessage(Message msg) {
      SampleActivity activity = mActivity.get();
      if (activity != null) {
         // ...
      }
   }
}

private final MyHandler mHandler = new MyHandler(this);

Now the splash has a handler reference, but the handler reference to splashActivity is weak and the Garbage Collector will not take it into account when removing them.

    
answered by 09.10.2018 / 01:50
source