#java #android #kotlin #crash
Вопрос:
Я обновил приложение, не меняя код, в предварительной версии все было нормально. Приложение выходит из строя после сворачивания, а затем открытия, при первоначальном запуске оно работает нормально, вылетает только при максимизации после сворачивания. Исполняемый код тот же, нет удаления lessonsContainer (присутствует в одном экземпляре в другом фрагменте), и он никоим образом не участвует во фрагменте фрагмента lessonsnewwordsfr. Ошибка:
5138-5138/soylekz.Droid E/AndroidRuntime: FATAL EXCEPTION: main
Process: soylekz.Droid, PID: 5138
java.lang.IllegalArgumentException: No view found for id 0x7f0a016f (soylekz.Droid:id/lessonsContainer) for fragment LessonsNewWordsFragment{5f3baba #6 id=0x7f0a016f}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1454)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:620)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1432)
at android.app.Activity.performStart(Activity.java:7923)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3359)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:57)
at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5358)
at android.app.ActivityThread.access$3600(ActivityThread.java:230)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2078)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7551)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
SDK изменен на последнюю версию. При отладке он проходит через те же строки в версиях до и после рестайлинга. Я не понимаю, в чем может быть дело, в каком направлении двигаться.
Добавить:
Уроки новые слова фрагмент.кт
class LessonsNewWordsFragment : BaseFragment<MainActivity, LessonsNewWordsPresenter>(),
LessonsNewWordsView,
LessonsSubtasksAdapter.OnItemClickListener {
lateinit var rvAdapterSubTasks: LessonsSubtasksAdapter
override val layoutId: Int
get() = R.layout.fragment_lessons_new_words
override fun createPresenter(): LessonsNewWordsPresenter = LessonsNewWordsPresenter(this)
override fun initViews(rootView: View?) {
val lessonId = arguments?.getInt(ARG_LESSON_ID)!!
var active_sections_:String = arguments?.getString(ARG_ACTIVE_SECTIONS)!!
active_sections_ = active_sections_.replace("/", "")
var active_sections: ActiveSections = Gson().fromJson<ActiveSections>(active_sections_, object : TypeToken<ActiveSections>() {}.type)
val soundAndTranslationFrag = SoundAndTranslationFragment.newInstance(lessonId)
val dictionaryCards = LessonCardsFragment.newInstance(lessonId)
val wordsOnPhoto = LessonPhotosFragment.newInstance(lessonId)
val exercises = NewWordsExercisesFragment.newInstance(lessonId)
rvAdapterSubTasks = LessonsSubtasksAdapter()
rvAdapterSubTasks.onItemClickListener = this
lessonsNewWordsRv.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
lessonsNewWordsRv.adapter = rvAdapterSubTasks
var arrayList = ArrayList<LessonsSubtasksModel>()
var isChecked = true;
if (active_sections.word == 1) {
arrayList.add(LessonsSubtasksModel(getString(R.string.subtaskTvSoundAndTrans), isChecked, soundAndTranslationFrag))
isChecked = false
}
if (active_sections.card == 1) {
arrayList.add(LessonsSubtasksModel(getString(R.string.subtaskTvDictionaryCards), isChecked, dictionaryCards))
isChecked = false
}
if (active_sections.photo == 1) {
arrayList.add(LessonsSubtasksModel(getString(R.string.subtaskTvWordsOnPhoto), isChecked, wordsOnPhoto))
isChecked = false
}
if (active_sections.wordexercise == 1) {
arrayList.add(LessonsSubtasksModel(getString(R.string.subtaskTvExercisesForMem), isChecked, exercises))
isChecked = false
}
rvAdapterSubTasks.setItems(arrayList)
replaceFragment(R.id.lessonsNewWordsContainer, rvAdapterSubTasks.getItem(0).fragment, null)
lessonsNewWordsRv.scrollToPosition(0)
}
override fun onItemClick(item: Int?, fragment: BaseFragment<*,*>) {
rvAdapterSubTasks.notifyDataSetChanged()
lessonsNewWordsRv.scrollToPosition(item!!)
replaceFragment(R.id.lessonsNewWordsContainer, fragment, null)
}
companion object {
private const val ARG_LESSON_ID = "arg_lesson_id"
private const val ARG_ACTIVE_SECTIONS = "arg_active_sections"
fun newInstance(lessonId: Int, active_sections: String): LessonsNewWordsFragment {
val args = Bundle()
val fragment = LessonsNewWordsFragment()
args.putInt(ARG_LESSON_ID, lessonId)
args.putString(ARG_ACTIVE_SECTIONS, active_sections)
fragment.setArguments(args)
return fragment
}
}
}
Базовый фрагмент.кт
abstract class BaseFragment<A : BaseActivity<*>, P : BasePresenter> : Fragment(), BaseView {
protected var presenter: P? = null
/**
* You this instead of [android.app.Fragment.getActivity]
*/
protected lateinit var activity: A
private var rootView: View? = null
/**
* Place your layout resource as return parameter
*
* @return resourceId of layout which designed for current fragment
*/
@get:LayoutRes
protected abstract val layoutId: Int
/**
* You should create an instance of your presenter here. After that you can use [presenter] everywhere in created fragment
*
* @return an instance of presenter for created fragment
*/
protected abstract fun createPresenter(): P
/**
* Initialize all views here.
* This method do the same as [android.app.Fragment.onCreateView]
*
* @param rootView already inflated view
*/
protected abstract fun initViews(rootView: View?)
override fun onAttach(context: Context?) {
super.onAttach(context)
@Suppress("UNCHECKED_CAST")
activity = getActivity() as A
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
presenter = createPresenter()
Utils.changeLang(context!!)
return inflater?.inflate(layoutId, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) = initViews(view)
/**
* Replaces existing fragment with allowing state loss
*
* @param containerId view where fragment will be replaced
* @param fragment new fragment
* @param tag for new fragment
*/
protected fun replaceFragment(@IdRes containerId: Int, fragment: BaseFragment<*, *>, tag: String?) {
fragmentManager?.beginTransaction()?.replace(containerId, fragment, tag)?.commitAllowingStateLoss()
}
protected fun replaceFragmentChild(@IdRes containerId: Int, fragment: BaseFragment<*, *>, tag: String?) {
childFragmentManager?.beginTransaction()?.replace(containerId, fragment, tag)?.commitAllowingStateLoss()
}
/**
* Adds fragment into backstack above existing fragment allowing state loss
*
* @param containerId view where fragment will be added
* @param fragment new fragment
* @param tag for new fragment
*/
protected fun addFragment(@IdRes containerId: Int, fragment: BaseFragment<*, *>, tag: String?) {
fragmentManager?.beginTransaction()?.replace(containerId, fragment, tag)?.addToBackStack(tag)
?.commitAllowingStateLoss()
}
protected fun addFragmentChild(@IdRes containerId: Int, fragment: BaseFragment<*, *>, tag: String?) {
childFragmentManager?.beginTransaction()?.replace(containerId, fragment, tag)?.addToBackStack(tag)
?.commitAllowingStateLoss()
}
override fun showProgressView() = activity.showProgressView()
override fun hideProgressView() = activity.hideProgressView()
}
Комментарии:
1. Можете ли вы поделиться своим фрагментным кодом здесь
2. Добавлен текст вопроса с кодом, вылетает после вызова replaceFragment