В настоящее время я вижу очень странное исключение nullpointer, которое я не могу объяснить сам.
У меня есть Activity, в котором размещены два фрагмента. Контекстное меню оценивается в host-activity, а затем вызывает общедоступную функцию в одном из фрагментов.
Хотя это хорошо работает для нескольких телефонов с Android 7, я обычно получаю исключение nullpointer на моем Samsung S7 с Android 8. Исключение nullpointer возникает, когда я пытаюсь получить доступ к любым элементам пользовательского интерфейса фрагмента внутри этого вызова функции!
Я уже проверил, что экземпляры фрагментов действительны, и они в порядке. Они полностью инициализированы и добавлены в onCreate хоста. Всякий раз, когда я запускаю функцию изнутри фрагмента, это нормально, но только не в том случае, если я вызываю ту же функцию из контекстного меню активности хостинга!
Сначала это выглядит как проблема с синхронизацией, потому что иногда это срабатывает, хотя относительно редко. В чем причина такого поведения и как мне исправить эту странную ошибку?
Спасибо Андреас
public class EpaperFragmentHost extends AppCompatActivity
{
private CustomViewPager mViewPager;
private Toolbar toolbar;
private EpaperPicture_Fragment EpaperPictureFrag;
private int Picture_Fragment_Position = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_connectfragmenthost);
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle( String.format( Locale.GERMAN,
getString(R.string.Connectingto_STRING) , mDeviceName) );
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new Connection_fragment_adapter(
getSupportFragmentManager() );
EpaperPictureFrag = EpaperPicture_Fragment.newInstance( );
mSectionsPagerAdapter.setFragment( Picture_Fragment_Position,
EpaperPictureFrag );
mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.epapermenu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id){
case R.id.menuitem_savepicture:
// This call will fail on some phones, but works on others!
// And not because EpaperPictureFrag would be null, but the
// myDrawView inside this instance is null!
EpaperPictureFrag.takeScreenshot( true);
break;
default:
break;
}
boolean result = super.onOptionsItemSelected(item);
return result;
}
}
а это фрагмент:
public class EpaperPicture_Fragment extends Fragment
{
public DrawView myDrawView;
public EpaperPicture_Fragment() {
// Required empty public constructor
}
public static EpaperPicture_Fragment newInstance( ) {
EpaperPicture_Fragment fragment = new EpaperPicture_Fragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_epaper_picture, container,
false);
btn_Clear = v.findViewById(R.id.clear_btn);
btn_addText = v.findViewById(R.id.addtext_btn);
btn_Transmit = v.findViewById(R.id.transmit_btn);
myDrawView = v.findViewById(R.id.epaper);
btn_Clear.setOnClickListener( this );
btn_addText.setOnClickListener(this);
btn_Transmit.setOnClickListener( this );
return v;
}
@Override
public void onClick(View v) {
switch( v.getId() ){
case R.id.transmit_btn:
// This call works!
takeScreenshot( true );
break;
default:
break;
}
}
public File takeScreenshot(boolean showToast) {
// THIS IS THE PROBLEMATIC SECTION!
// Why can myDrawView be null, if the fragment exists?
myDrawView.setDrawingCacheEnabled(true);
Bitmap cachedBitmap = myDrawView.getDrawingCache();
Bitmap copyBitmap = cachedBitmap.copy(Bitmap.Config.RGB_565, true);
myDrawView.destroyDrawingCache();
// ...
}
}
Хорошо, решение:
Я изменил проверку доступа к хранилищу в базовом классе на новый режим.
И эта проверка вызвала воссоздание каждого действия, унаследованного базовым классом, после проверки прав доступа! Я нашел это, сгенерировав все методы перезаписи базового класса и выполнив лог-вывод в каждом. Это была ужасная последовательность разрушения и создания.
К сожалению, примерно в то же время я поменял свой тестовый телефон ...
Похоже, вы делаете что-то за пределами указанного поведения. Разместите код, чтобы получить лучшую помощь, на данный момент мы можем только догадываться.