这是我的代码,我想把我的内部类静态化以避免内存泄漏。
让我解释一下......我已经制作了一个带有runnable和处理程序的计时器。但是,当我检查android studio中的内存使用情况时,我会看到内存正在上升,然后上升。
我认为我的实施有问题,但我不知道它是什么。
我的研究导致我用runnable创建一个静态类,但是当我这样做时,我无法访问外部classe变量或振动器服务。
public class ActiviteCompteARebours extends AdMobActivity {
private int compteurTimer,
int_rowTime_display,
int_total_time_in_millis;
private boolean doubleBackExit;
private boolean bln_addTime = false;
private int pressed = 0;
private final int PERCENT = 120000;
private final int INT_MILLIS = 1000;
private final int INTERVALLE = 100;
private final int AJOUTE_30_SEC = 30000;
private final String str_compteurEntrainement = "compteurEntrainement";
private Handler handler;
private TimerRunnable runnable;
private Button btn_passer;
private TextView txt_countDown;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_countdown);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
btn_passer = (Button) findViewById(R.id.btn_entrainement);
txt_countDown = (TextView) findViewById(R.id.txtView_countDown);
int_total_time_in_millis = PERCENT; //Temps total en mili secondes
int_rowTime_display = PERCENT; //Temps total pour l'affichage
runnable = new TimerRunnable();
handler = new Handler();
progressBar.setMax (PERCENT); //Valeur max de la progress bar = 2 minutes (120000 ms)
progressBar.setProgress(PERCENT); //Fixe la valeur de la progresse bar a 2 minutes
Intent intent = getIntent();
compteurTimer = intent.getExtras().getInt(str_compteurEntrainement,1); //
txt_countDown.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runnable.addTime(); //on stop le timer
handler.removeCallbacksAndMessages(runnable); //on annule les message du handler
int_total_time_in_millis =
runnable.getTimeInMillis() + AJOUTE_30_SEC ; //recupere le temps et ajoute 30 sec
bln_addTime = false; //sinon le timer ne se lance pas
int_rowTime_display = int_total_time_in_millis; //pour l'affiche du nouveau temps
progressBar.setMax(int_total_time_in_millis); //fixe le max
progressBar.setProgress (int_total_time_in_millis); //fixe la valeur de la progressBar
handler.postDelayed(runnable,INTERVALLE); //relance le timer
}
});
btn_passer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { //Action lors du click sur le boutton "passer"
if(runnable != null){
runnable.killRunnable(); //Retour à l'activite precedente
}
}
});
//Run Timer
//call handler post delayed to resume the runnable
handler.postDelayed(runnable, 100);
}//onCreate
private class TimerRunnable implements Runnable{
private final Vibrator vibreur = (Vibrator) getSystemService(VIBRATOR_SERVICE); //service de vibration
private final int INT_SEC = 60;
private boolean isCanceled = false;
private int int_progress_value;
@Override
public void run() {
//if time is added
if (bln_addTime){
runnable = null;
}//if the timer is canceled or the total time = the progress time
else if(isCanceled || int_total_time_in_millis == int_progress_value){
//set runnable to null
runnable = null;
vibreur.vibrate(200);
workoutIntent();
//return
return;
}
else{
//increment int_progess_value
int_progress_value += INTERVALLE;
//update the time in the screen for the countdown
int_rowTime_display -= INTERVALLE;
progressBar.setSecondaryProgress(int_progress_value);
//get the time in seconds by dividing by 1000
int row_min = int_rowTime_display / INT_MILLIS;
String time = ""+ row_min / INT_SEC + ":";
String sec = ""+row_min % INT_SEC;
if(row_min % INT_SEC < 10){
time += "0" + sec;
}else{
time += sec;
}
//divide row_min by 60 to get minutes. and row_min % 60 to get seconds
txt_countDown.setText(time);
//controle le temps pour vibrer lors des 3 dernières secondes
//on utilise l'incrémentation de la progressbar pour être plus précis
//on prends 1 sentième avant pour anticiper le postDelayed de une seconde
/*if (int_progress_value == int_total_time_in_millis-1110 ||
int_progress_value == int_total_time_in_millis-2110 ||
int_progress_value == int_total_time_in_millis-3110){
*/
if(int_rowTime_display == 300 || int_rowTime_display == 200){vibreur.vibrate(100);}
/* show add 5 seconds after countDown start */
if ((compteurTimer == 2 || compteurTimer == 4) && int_progress_value == 5000){
showInterstitial(); //adMob
}
}
handler.postDelayed(this,INTERVALLE);
}//run
public void killRunnable(){
//when timer is paused or stopped isCanceled is set to true.
isCanceled = true;
}
public int getTimeInMillis(){
return int_rowTime_display;
}
public void addTime(){
//when timer is paused or stopped isCanceled is set to true.
bln_addTime = true;
}
}//Runnable
void workoutIntent() {
//création d'un nouvel intent vers l'entraînement
Intent workout = new Intent(ActiviteCompteARebours.this, ActiviteEntrainement.class);
//on augmente le compteur ce qui permettra de passer à la série suivante sur l'intent entrainement
compteurTimer++;
//ajout de l'extra pour l'intent entrainement
workout.putExtra(str_compteurEntrainement, compteurTimer);
//on cherche si une activité workout existe et on la ramène en première position
workout.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
//Comme l'activité ActiviteEntrainement attend un résultat on retourne le résultat OK
setResult(RESULT_OK, workout);
// fin de l'activité ActiviteCompteARebours
finish();
}
protected void onDestroy() {
super.onDestroy();
Log.d("TIMER", "Arrêt du timer, onDestroy Method");
if(runnable != null){
runnable.killRunnable();
handler.removeCallbacks(runnable);
runnable = null;
}
}
`
答案 0 :(得分:0)
仅仅因为内部类在外部类中被编写,它无法访问其变量或方法。这是因为它没有引用外部类的对象。
自由访问并发运行的线程的变量也会造成严重的正确性问题,因为在线程B尝试修改其变量的时间点,没有人能够知道线程A将处于哪个状态。正确的方法是使用AsyncTask
,如https://developer.android.com/guide/components/processes-and-threads.html中所述,其中doInBackground
方法用于将信息从调用线程传递到新线程,onPostExecute
携带信息回到来电者。