Это может сработать, в зависимости от того, когда вам нужно проверить 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
Чтобы понять, почему , take a look при реализации 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()
. И вообще, если это не вызвано, есть веские причины (система срочно нуждается в освобождении памяти и не имеет времени для завершения вызовов жизненного цикла активности, или нет причин для фактического уничтожения активности). Что касается, если есть другие способы имитации этого, по крайней мере, я не могу думать ни о каком.
Это не будет работать для более ранних уровней api. При этом вы всегда можете использовать аннотацию, чтобы сказать, что эта конкретная часть теста действительна только для уровней api более высокого уровня, а не ниже определенного уровня. Это все равно позволит вам написать тесты для более низких уровней api. –