Использование Singleton MainActivity? - PullRequest
0 голосов
/ 14 декабря 2018

Я хотел бы знать, является ли плохой выбор дизайна использовать одноэлементную MainAcitivity следующим образом:

public class MainActivity extends AppCompatActivity ... {
   public static MainActivity mainActivitySingleton;
   ....
   @Override
   protected void onCreate(Bundle savedInstanceState) {
   mainActivitySingleton=this;

Например, во многих случаях, когда мне нужен доступ к контексту, который я использую getContext(), но иногда (я не знаю почему) getContext() возвращает null, что приводит к исключению времени выполнения.В итоге я использовал mainActivitySingleton, который я создал вместо getContext().

Мой мизинец говорит мне, что это плохой выбор дизайна!если это так, кто-нибудь может объяснить, почему?

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Хранение статической ссылки на объект Activity или Context является одним из случаев утечки памяти, который приводит к дополнительному потреблению памяти, а затем к потере производительности.Если никакая ссылка не указывает на объект, то он помечается как кандидат на сборку мусора.Когда объект больше не используется в программе, но сборщик мусора не может освободить его память, это рассматривается как случай утечки памяти.Следовательно, в случае статической ссылки на Activity его память не может быть освобождена после вызова метода onDestroy.

Если вы действительно хотите хранить статическую ссылку на экземпляр Activity или Context, рекомендуется использовать WeakReference.

public class MyActivity extends AppCompatActivity {

    private static WeakReference<Context> sContextReference;

    @Override 
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sContextReference = new WeakReference<>(this);
    }
} 

Использование:

Context context = sContextReference.get();

.

ОБНОВЛЕНИЕ:

Лучшим решением для сохранения ссылки на экземпляр Context является создание и хранение слабой ссылки на него в классе Application.Таким образом, мы уверены, что только одна ссылка указывает на контекст приложения во время выполнения приложения.

MyApplication.java

import android.app.Application;
import android.content.Context;

import java.lang.ref.WeakReference;

public class MyApplication extends Application {

    private static WeakReference<Context> sContextReference;

    @Override
    public void onCreate() {
        super.onCreate();
        sContextReference = new WeakReference<>(getApplicationContext());
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        sContextReference.clear();
    }

    public static Context getContext() {
        return sContextReference.get();
    }

}

manifest.xml

<application
    android:name="path.to.MyApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:theme="@style/AppTheme.NoActionBar">

    ...

</application>

Использование:

Context context = MyApplication.getContext();
0 голосов
/ 14 декабря 2018

Никогда не делай этого. Это плохой шаблон дизайна.Вы не должны сохранять экземпляр активности как статический экземпляр, потому что это потенциальная утечка памяти.Если вы вызываете метод getContext() в экземпляре фрагмента, вам следует вызвать getContext() в этом жизненном цикле onActivityCreated() метод .

Как это:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Context context = getContext();
}
...