Симуляция isDestroyed() в Android
Я обнаружил, что мне нужно позвонить isDestroyed()
проверить, является ли действие более недействительным. Я сделал это, и все работает отлично.
Тем не менее, включение isDestroyed()
вынуждает меня поднять уровень API Android до уровня (17), который мне не нравится. Я бы предпочел не делать этого.
Я думаю, что я могу симулировать isDestroyed()
просто переопределив onDestroy()
в моей деятельности. Когда этот метод вызывается, я могу просто сохранить этот факт в логическом значении, а затем использовать его для предоставления своей собственной версии isDestroyed()
(смена названия конечно).
Будет ли что-то так просто, как эта работа? Я вижу много ссылок на onDestroy()
не вызывается в некоторых случаях. Есть ли другой способ симулировать это?
2 ответа
Видя, как код структуры:
public boolean isDestroyed() {
return mDestroyed;
}
final void performDestroy() {
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy();
if (mLoaderManager != null) {
mLoaderManager.doDestroy();
}
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
}
Я бы сказал, что вы достаточно безопасны, чтобы использовать свой собственный флаг, установленный в onDestroy
, вы получите тот же результат, что и при использовании флага платформы, если что-то не падает mWindow.destroy()
или же mFragments.dispatchDestroy()
Это может работать, в зависимости от того, когда вам нужно проверить isDestroyed()
,
Если вы проверите для isDestroyed()
в Fragment.onDestroy()
обратный вызов, смоделированная реализация, реализованная, как вы описываете, вернет false
, в то время как Activity.isDestroyed()
вернусь true
, Если вы проверите для isDestroyed()
"позже", это будет работать. Вы можете проверить это с помощью следующего приложения для тестирования:
package com.example.test.myapplication;
import android.app.Activity;
import android.app.Fragment;
import android.os.Handler;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends Activity {
private boolean mOnDestroyCalled;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new MainFragment())
.commit();
}
}
@Override
protected void onDestroy() {
mOnDestroyCalled = true;
super.onDestroy();
}
public boolean isDestroyed_SIMULATED() {
return mOnDestroyCalled;
}
public static class MainFragment extends Fragment {
@Override
public void onDestroy() {
super.onDestroy();
final MainActivity mainActivity = (MainActivity)getActivity();
dumpIsDestroyedImplementations("In Fragment.onDestroy() ", mainActivity);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
dumpIsDestroyedImplementations("A while later ", mainActivity);
}
}, 500);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final TextView textView = new TextView(getActivity());
textView.setText("Hello world!");
return textView;
}
private void dumpIsDestroyedImplementations(String prefix, MainActivity mainActivity) {
Log.i("IsDestroyedTest", prefix + "isDestroyed(): " +
mainActivity.isDestroyed() +
" isDestroyed_SIMULATED(): " + mainActivity.isDestroyed_SIMULATED());
}
}
}
Если вы запустите это, а затем нажмите кнопку Назад на устройстве, adb logcat -s IsDestroyedTest
даст вам следующий вывод:
I/IsDestroyedTest( 2143): In Fragment.onDestroy() isDestroyed(): true isDestroyed_SIMULATED(): false
I/IsDestroyedTest( 2143): A while later isDestroyed(): true isDestroyed_SIMULATED(): true
Чтобы понять почему, взгляните на то, как isDestroyed()
реализовано.
public boolean isDestroyed() {
return mDestroyed;
}
...
final void performDestroy() {
mDestroyed = true;
...
mFragments.dispatchDestroy();
onDestroy();
...
}
В этом случае мы можем концептуально переписать его следующим образом:
final void performDestroy() {
mDestroyed = true;
...
MainFragment.onDestroy() // Called by mFragments.dispatchDestroy();
mOnDestroyCalled = true; // From MainActivity.onDestroy()
super.onDestroy(); // From MainActivity.onDestroy()
...
}
И легко понять, почему мы получаем вывод logcat, который мы получаем.
относительно onDestroy()
не вызывая иногда, эта проблема не будет зависеть от моделирования isDestroyed()
, И, как правило, если он не вызывается, на это есть веские причины (системе срочно нужно освободить память и не успеть завершить вызовы жизненного цикла действия, или нет причины фактически уничтожить действие). Относительно того, есть ли другие способы симулировать это, по крайней мере, я не могу думать ни о каком.