根据预发布报告,由于 FragmentActivity 在某些设备上失败而入职 activity
Onboarding activity as FragmentActivity failing on certain devices per Pre-launch report
Android 新来的。任何帮助表示赞赏。所以我将我的应用程序发布到 Google Play 控制台。我在做发布前报告时遇到了一些问题。该应用程序在 4 台设备 运行ning Android 6 和 7 上失败。问题在于入职 activity。我已经展示了 OnBoardActivity class 和其中一个 OnboardingFragments(除了每个透视布局中的图片不同之外,它们都是相同的(R.id.onboardingscreen_1,R.id.onboardingscreen_2, 等等).
我发现致命崩溃是一个内存问题 "Caused by: java.lang.OutOfMemoryError: Failed to allocate a 132710412 byte allocation with 33554432 free bytes and 120MB until OOM." logcat 中引起我注意的那一行让我认为这是一个 OnBoardActivity 问题:
" 在 Util.OnboardingFragment2.onCreateView(OnboardingFragment2.java:21)"
其中 3 个设备出现故障。
Galaxy J7 因 logcat 中的差异而失败:
"java.lang.IllegalStateException: Fragment already added: OnboardingFragment3{fe12a94 #2 id=0x7f0a0099}"
我不知道为什么我的应用会尝试分配 132 MB???我无法用模拟器重新创建其中任何一个。当我查看应用程序崩溃的视频时,这 4 台设备在第一次启动时是正确的。它要么在尝试启动 OnBoardActivity 时失败,要么在移动到下一个或上一个入职片段时失败。
我不知道该怎么办!我需要一些关于第一个 运行 的快速说明。我确信我正在适当地启动 OnBoardActivity(从 MainActivity):
prefs = getSharedPreferences(Util.APP_NAME, MODE_PRIVATE);
if(!prefs.getBoolean("onboarding_complete", false)){
Intent intent = new Intent(this, OnBoardActivity.class);
startActivity(intent);
finish();
return;
}
Google提供的这4次失败的log是:
<!-- language: lang-none -->
Caused by: android.view.InflateException: Binary XML file line #26: Error inflating class <unknown>
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.view.LayoutInflater.createView(LayoutInflater.java:645)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at Util.OnboardingFragment2.onCreateView(OnboardingFragment2.java:21)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2346)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1428)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2215)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:649)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:167)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1238)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1086)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1616)
at android.view.View.measure(View.java:19834)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:19834)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6164)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19834)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6164)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19834)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6164)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:692)
at android.view.View.measure(View.java:19834)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2358)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1430)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1679)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1306)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6579)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 132710412 byte allocation with 33554432 free bytes and 120MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:620)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:455)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1152)
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:859)
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:710)
at android.content.res.Resources.getDrawable(Resources.java:776)
at android.content.Context.getDrawable(Context.java:530)
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:358)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:198)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:186)
at android.support.v7.content.res.AppCompatResources.getDrawable(AppCompatResources.java:100)
at android.support.v7.widget.AppCompatImageHelper.loadFromAttributes(AppCompatImageHelper.java:58)
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:77)
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:67)
... 58 more
代码如下:
public class OnBoardActivity extends FragmentActivity {
private ViewPager pager;
private SmartTabLayout indicatior;
private ButtonFlat skip;
private ButtonFlat next;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_onboarding);
pager = findViewById(R.id.pager);
indicatior = findViewById(R.id.indicator);
skip = findViewById(R.id.skip);
next = findViewById(R.id.next);
FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
List<Fragment> f = getSupportFragmentManager().getFragments();
for(int i=0; i<f.size(); i++){
Log.d("Fragment Get", "Fragment: " + Integer.toString(i) + " "
+ f.get(i).getClass().getName());
}
Log.d("Fragment Pos", "Position: " + Integer.toString(position));
switch (position) {
case 0 :
Log.d("Fragment Ret", "Returning new OnboardingFragment1\n");
return new OnboardingFragment1();
case 1 :
Log.d("Fragment Ret", "Returning new OnboardingFragment2\n");
return new OnboardingFragment2();
case 2 :
Log.d("Fragment Ret", "Returning new OnboardingFragment3\n");
return new OnboardingFragment3();
default: return null;
}
}
@Override
public int getCount() {
return 3;
}
@Override
public Parcelable saveState(){
return null;
}
};
pager.setAdapter(adapter);
indicatior.setViewPager(pager);
indicatior.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
@Override
public void onPageSelected(int position) {
if(position == 2){
skip.setVisibility(View.GONE);
next.setText("Done");
} else {
skip.setVisibility(View.VISIBLE);
next.setText("Next");
}
}
});
skip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finishOnboarding();
}
});
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(pager.getCurrentItem() == 2){
finishOnboarding();
} else {
pager.setCurrentItem(pager.getCurrentItem() + 1, true);
}
}
});
}
private void finishOnboarding() {
SharedPreferences preferences =
getSharedPreferences(Util.APP_NAME, MODE_PRIVATE);
preferences.edit()
.putBoolean("onboarding_complete",true).apply();
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
public class OnboardingFragment1 extends Fragment {
@Override
public View onCreateView(@Nullable LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setRetainInstance(true);
return inflater != null ? inflater.inflate(
R.layout.onboarding_screen1,
container,
false
) : null;
}
}
希望有人能帮忙!谢谢阅读! -马特
根据我的评论,我在对片段进行了大量研究后找到了解决方案。有时 FragmentStatePageAdapter 会尝试膨胀它认为已删除但实际上尚未删除的视图。通过将 OnboardingFragment 更改为:
现在效果很好
public class OnboardingFragment1 extends Fragment {
@Override
public View onCreateView(@Nullable LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return getView() !=null ? getView(): inflater.inflate(R.layout.onboarding_screen1, container, false);
}
Android 新来的。任何帮助表示赞赏。所以我将我的应用程序发布到 Google Play 控制台。我在做发布前报告时遇到了一些问题。该应用程序在 4 台设备 运行ning Android 6 和 7 上失败。问题在于入职 activity。我已经展示了 OnBoardActivity class 和其中一个 OnboardingFragments(除了每个透视布局中的图片不同之外,它们都是相同的(R.id.onboardingscreen_1,R.id.onboardingscreen_2, 等等).
我发现致命崩溃是一个内存问题 "Caused by: java.lang.OutOfMemoryError: Failed to allocate a 132710412 byte allocation with 33554432 free bytes and 120MB until OOM." logcat 中引起我注意的那一行让我认为这是一个 OnBoardActivity 问题:
" 在 Util.OnboardingFragment2.onCreateView(OnboardingFragment2.java:21)"
其中 3 个设备出现故障。
Galaxy J7 因 logcat 中的差异而失败:
"java.lang.IllegalStateException: Fragment already added: OnboardingFragment3{fe12a94 #2 id=0x7f0a0099}"
我不知道为什么我的应用会尝试分配 132 MB???我无法用模拟器重新创建其中任何一个。当我查看应用程序崩溃的视频时,这 4 台设备在第一次启动时是正确的。它要么在尝试启动 OnBoardActivity 时失败,要么在移动到下一个或上一个入职片段时失败。
我不知道该怎么办!我需要一些关于第一个 运行 的快速说明。我确信我正在适当地启动 OnBoardActivity(从 MainActivity):
prefs = getSharedPreferences(Util.APP_NAME, MODE_PRIVATE);
if(!prefs.getBoolean("onboarding_complete", false)){
Intent intent = new Intent(this, OnBoardActivity.class);
startActivity(intent);
finish();
return;
}
Google提供的这4次失败的log是:
<!-- language: lang-none -->
Caused by: android.view.InflateException: Binary XML file line #26: Error inflating class <unknown>
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.view.LayoutInflater.createView(LayoutInflater.java:645)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at Util.OnboardingFragment2.onCreateView(OnboardingFragment2.java:21)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2346)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1428)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2215)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:649)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:167)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1238)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1086)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1616)
at android.view.View.measure(View.java:19834)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:19834)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6164)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19834)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6164)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19834)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6164)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:692)
at android.view.View.measure(View.java:19834)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2358)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1430)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1679)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1306)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6579)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 132710412 byte allocation with 33554432 free bytes and 120MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:620)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:455)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1152)
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:859)
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:710)
at android.content.res.Resources.getDrawable(Resources.java:776)
at android.content.Context.getDrawable(Context.java:530)
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:358)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:198)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:186)
at android.support.v7.content.res.AppCompatResources.getDrawable(AppCompatResources.java:100)
at android.support.v7.widget.AppCompatImageHelper.loadFromAttributes(AppCompatImageHelper.java:58)
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:77)
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:67)
... 58 more
代码如下:
public class OnBoardActivity extends FragmentActivity {
private ViewPager pager;
private SmartTabLayout indicatior;
private ButtonFlat skip;
private ButtonFlat next;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_onboarding);
pager = findViewById(R.id.pager);
indicatior = findViewById(R.id.indicator);
skip = findViewById(R.id.skip);
next = findViewById(R.id.next);
FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
List<Fragment> f = getSupportFragmentManager().getFragments();
for(int i=0; i<f.size(); i++){
Log.d("Fragment Get", "Fragment: " + Integer.toString(i) + " "
+ f.get(i).getClass().getName());
}
Log.d("Fragment Pos", "Position: " + Integer.toString(position));
switch (position) {
case 0 :
Log.d("Fragment Ret", "Returning new OnboardingFragment1\n");
return new OnboardingFragment1();
case 1 :
Log.d("Fragment Ret", "Returning new OnboardingFragment2\n");
return new OnboardingFragment2();
case 2 :
Log.d("Fragment Ret", "Returning new OnboardingFragment3\n");
return new OnboardingFragment3();
default: return null;
}
}
@Override
public int getCount() {
return 3;
}
@Override
public Parcelable saveState(){
return null;
}
};
pager.setAdapter(adapter);
indicatior.setViewPager(pager);
indicatior.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
@Override
public void onPageSelected(int position) {
if(position == 2){
skip.setVisibility(View.GONE);
next.setText("Done");
} else {
skip.setVisibility(View.VISIBLE);
next.setText("Next");
}
}
});
skip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finishOnboarding();
}
});
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(pager.getCurrentItem() == 2){
finishOnboarding();
} else {
pager.setCurrentItem(pager.getCurrentItem() + 1, true);
}
}
});
}
private void finishOnboarding() {
SharedPreferences preferences =
getSharedPreferences(Util.APP_NAME, MODE_PRIVATE);
preferences.edit()
.putBoolean("onboarding_complete",true).apply();
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
public class OnboardingFragment1 extends Fragment {
@Override
public View onCreateView(@Nullable LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setRetainInstance(true);
return inflater != null ? inflater.inflate(
R.layout.onboarding_screen1,
container,
false
) : null;
}
}
希望有人能帮忙!谢谢阅读! -马特
根据我的评论,我在对片段进行了大量研究后找到了解决方案。有时 FragmentStatePageAdapter 会尝试膨胀它认为已删除但实际上尚未删除的视图。通过将 OnboardingFragment 更改为:
现在效果很好public class OnboardingFragment1 extends Fragment {
@Override
public View onCreateView(@Nullable LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return getView() !=null ? getView(): inflater.inflate(R.layout.onboarding_screen1, container, false);
}