Я уже несколько месяцев пишу приложение для Android в качестве хобби. Теперь я пришел к тому, что мне пришлось осознать, что реальный мир не так прост, как могут звучать некоторые учебные пособия, и что приложение работает по-разному на нескольких устройствах. В настоящее время меня беспокоит использование памяти и процессора в моих приложениях. Я действительно никогда не трачу время на оптимизацию или даже на размышления о своих приложениях с точки зрения использования памяти, и хорошо, я пойду, осознавая, что, вероятно, я действительно запутался во многих моментах, и есть много чего исправить.
К сожалению, я с трудом ищу учебники и объяснения, которые актуальны и понятны для новичков. Многие учебники имеют дело со старыми версиями андроид-студии, и очень хорошие учебники о работе с DDMS. Я чувствую, что в новом Android Profiler (в Android Studio 3.0) отсутствуют некоторые важные идеи.
Было бы замечательно, если бы вы помогли мне избавиться от некоторых недоразумений, которые я в настоящее время раздражал долгой ночной чтением многих инструкций и инструкций.
В настоящее время я задаюсь вопросом о BroadcastReceiver в деятельности, которая часто используется.
Так, например, у меня есть музыкальное приложение. MainActivity
запускает Service
для управления воспроизведением музыки. Это Service
сообщает деятельности о текущем состоянии воспроизведения и прошедшем времени воспроизведения.
Отчетность решается путем отправки намерения из Service
во внутренний BroadcastReceiver
в пределах именованного MainActivity
.
Вот упрощенный пример, чтобы вы поняли, что я имею в виду:
public class MainActivity extends Activity {
private class MusicPlayerBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//update UI elements
seekBar.post(() -> seekBar.setProgress(POSITION)); //using post for thread safeness?
//lots of other UI calls
}
}
}
Поскольку я не был уверен, что следующие проблемы возникают из-за неправильной реализации, я решил опубликовать полный код получения намерения:
int currentPos = intent.getIntExtra(KEY_POSITION, -1);
//check if large player is showing, if not it should display mini Player
if(playerRootView.getVisibility() != View.VISIBLE) {
mini_Player.setVisibility(View.VISIBLE);
}
//if the loading hasn't been triggered away yet, this one will help
if(relativeLayoutLoading.getVisibility() == View.VISIBLE) {
relativeLayoutLoading.setVisibility(View.GONE);
playerControls.setVisibility(View.VISIBLE);
}
TrackModel mCurrentTrack=MusicDataMng.getInstance().getCurrentTrackModel();
if (currentPos > 0 && mCurrentTrack != null) {
long duration = currentPos / 1000;
String minute = String.valueOf((int) (duration / 60));
String seconds = String.valueOf((int) (duration % 60));
if (minute.length() < 2) {
minute = "0" + minute;
}
if (seconds.length() < 2) {
seconds = "0" + seconds;
}
String timePassed = minute + ":" + seconds;
if(!seeking) {
// will update the "progress" propriety of seekbar until it reaches progress
seekBar.post(() -> {
ObjectAnimator animation = ObjectAnimator.ofInt(seekBar, "progress", currentPos);
animation.setDuration(1000); // 0.5 second
animation.setInterpolator(new LinearInterpolator());
animation.start();
});
} else {
seekBar.post(() -> seekBar.setProgress(currentPos));
}
mini_ProgressBar.post(() -> mini_ProgressBar.setProgress(currentPos));
trackDurationStart.post(() -> trackDurationStart.setText(timePassed));
}
То, что я теперь вижу в Android Profiler при записи памяти после того, как начал играть песню, это:

Мои вопросы по этому поводу следующие:
- Мне кажется, что для каждого намерения не следует обновлять позицию экземпляра BroadcastReceiver. Почему они до сих пор хранятся и не удаляются после GC?
- Экземпляры содержат ссылку на MainActivity в
arg$1.this$0
- из идентификатора ссылки, я вижу, что они указывают на один и тот же
MainActivity
. Означает ли это, что они просто хранят указатель на эту ссылку или каждый экземпляр BroadcastReceiver хранит полную ссылку на MainActivity? Если это так, это будет означать интенсивное использование памяти, верно?
- Исчезнет ли это неправильное поведение, когда я сделаю
BroadcastReceiver
статическим, а затем добавлю конструктор, который установит WeakReferences, как описано здесь ?
Если вы чувствуете, что я что-то упустил из-за этой темы о производительности, или мне следует прочитать то или иное руководство или учебник, я был бы очень благодарен за любую рекомендацию.
Заранее спасибо