Android应用更换Dashboard为主活动后闪屏结束后崩溃求助
应用跳转至DashboardActivity时崩溃问题
原本RadioActivity运行完全正常,将DashboardActivity设为主活动后,用户可通过Dashboard按钮跳转至RadioActivity,但现在应用在闪屏页结束进入引导页后,跳转至DashboardActivity时持续崩溃。
相关代码
SplashScreen
private static int SPLASH_TIMER = 8000; ImageView backgroundImage; ImageView theLogo; TextView poweredByLine; Animation sideAnim, bottomAnim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash_screen); getWindow().setFlags(WindowManager.LayoutParams.FLAGS_CHANGED,WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); setContentView(R.layout.activity_splash_screen); backgroundImage = findViewById(R.id.background_image); theLogo = findViewById(R.id.the_Logo); poweredByLine = findViewById(R.id.powered_by_line); sideAnim = AnimationUtils.loadAnimation(this, R.anim.side_anim); bottomAnim = AnimationUtils.loadAnimation(this, R.anim.bottom_anim); backgroundImage.setAnimation(sideAnim); theLogo.setAnimation(sideAnim); poweredByLine.setAnimation(bottomAnim); new Handler().postDelayed(new Runnable() { @Override public void run() { Intent intent = new Intent(getApplicationContext(), OnBoarding.class); startActivity(intent); finish(); } },SPLASH_TIMER); }
OnBoarding
CardView nextCard; LinearLayout dotsLayout; ViewPager viewPager; TextView[] dots; int currentPosition; SaveState saveState ; @RequiresApi(api = Build.VERSION_CODES.M) @Override protected void onCreate(Bundle savedInstanceState) { getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); super.onCreate(savedInstanceState); setContentView(R.layout.activity_onboarding); nextCard = findViewById(R.id.nextCard); dotsLayout = findViewById(R.id.dotsLayout); viewPager = findViewById(R.id.slider); dotsFunction(0); saveState = new SaveState(OnBoarding.this,"OB"); if (saveState.getState() == 1){ Intent i = new Intent(OnBoarding.this,DashboardActivity.class); startActivity(i); finish(); } OnBoardingAdapter adapter = new OnBoardingAdapter(this); viewPager.setAdapter(adapter); nextCard.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { viewPager.setCurrentItem(currentPosition+1,true); } }); viewPager.setOnPageChangeListener(onPageChangeListener); } @RequiresApi(api = Build.VERSION_CODES.M) private void dotsFunction(int pos){ dots = new TextView[4]; dotsLayout.removeAllViews(); for (int i = 0; i < dots.length ; i++){ dots[i] = new TextView(this); dots[i].setText(Html.fromHtml("•")); dots[i].setTextColor(getColor(R.color.white)); dots[i].setTextSize(30); dotsLayout.addView(dots[i]); } if (dots.length > 0){ dots[pos].setTextColor(getColor(R.color.teal_700)); dots[pos].setTextSize(40); } } ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} @RequiresApi(api = Build.VERSION_CODES.M) @Override public void onPageSelected(int position) { dotsFunction(position); currentPosition = position; if (currentPosition <= 2){ nextCard.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { viewPager.setCurrentItem(currentPosition+1); } }); }else{ nextCard.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { saveState.setState(1); Intent i = new Intent(OnBoarding.this, DashboardActivity.class); startActivity(i); finish(); } }); } } @Override public void onPageScrollStateChanged(int state) {} };
DashboardActivity
public class DashboardActivity extends AppCompatActivity implements View.OnClickListener{ private ImageView imageViewWebsite,imageViewEvents,imageViewLive, imageViewVideos,imageViewBranches,imageViewDonate, imageViewEkuwe,imageViewRadio,imageViewAudio; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dashboard); imageViewWebsite = (ImageView) findViewById(R.id.website_card); imageViewEvents = (ImageView) findViewById(R.id.event_card); imageViewLive = (ImageView) findViewById(R.id.live_card); imageViewVideos = (ImageView) findViewById(R.id.videos_card); imageViewBranches = (ImageView) findViewById(R.id.branches_card); imageViewDonate = (ImageView) findViewById(R.id.donate_card); imageViewEkuwe = (ImageView) findViewById(R.id.ekuwe_card); imageViewRadio = (ImageView) findViewById(R.id.radio_card); imageViewAudio = (ImageView) findViewById(R.id.audio_card); imageViewWebsite.setOnClickListener(this); imageViewEvents.setOnClickListener(this); imageViewLive.setOnClickListener(this); imageViewVideos.setOnClickListener(this); imageViewBranches.setOnClickListener(this); imageViewDonate.setOnClickListener(this); imageViewEkuwe.setOnClickListener(this); imageViewRadio.setOnClickListener(this); imageViewAudio.setOnClickListener(this); } @Override public void onClick(View v) { Intent i; switch (v.getId()){ case R.id.website_card : i = new Intent(this, WebsiteActivity.class);startActivity(i); break; case R.id.event_card : i = new Intent(this,EventsActivity.class);startActivity(i); break; case R.id.live_card : i = new Intent(this, LiveActivity.class);startActivity(i); break; case R.id.videos_card : i = new Intent(this, VideoActivity.class);startActivity(i); break; case R.id.branches_card : i = new Intent(this,BranchesActivity.class);startActivity(i); break; case R.id.donate_card : i = new Intent(this, DonateActivity.class);startActivity(i); break; case R.id.ekuwe_card : i = new Intent(this,EkuweActivity.class);startActivity(i); break; case R.id.radio_card : i = new Intent(this,RadioActivity.class);startActivity(i); break; case R.id.audio_card : i = new Intent(this,AudioActivity.class);startActivity(i); break; default:break; } } }
RadioActivity
public class RadioActivity extends AppCompatActivity { private TextView nowPlaying; private ImageView playStop; private BroadcastReceiver broadcastReceiver; private String nowPlayingData = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_radio); playStop = findViewById(R.id.playStopBtn); nowPlaying = findViewById(R.id.radioStationNowPlaying); setIsPlaying(false); processPhoneListenerPermission(); broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE); if (tm != null) { if (tm.getCallState() == TelephonyManager.CALL_STATE_RINGING) { if (getIsPlaying()) { stop(); } System.exit(0); } } } }; IntentFilter filter = new IntentFilter(); filter.addAction("android.intent.action.PHONE_STATE"); registerReceiver(broadcastReceiver, filter); loadNowPlaying(); playStop.setOnClickListener(view -> { if (isNetworkAvailable()) { if (getIsPlaying()) { stop(); } else { play(); } } else { Toast.makeText(getApplicationContext(), "No internet", Toast.LENGTH_LONG).show(); } }); } private void loadNowPlaying() { Thread t = new Thread() { public void run() { try { while (!isInterrupted()) { runOnUiThread(() -> reloadShoutCastInfo()); Thread.sleep(20000); } } catch (InterruptedException ignored) {} } }; t.start(); } private void reloadShoutCastInfo() { if (isNetworkAvailable()) { AsyncTaskRunner runner = new AsyncTaskRunner(); runner.execute(); } } @SuppressLint("StaticFieldLeak") private class AsyncTaskRunner extends AsyncTask<String, String, String> { @Override protected String doInBackground(String... params) { FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever(); mmr.setDataSource(STREAMING_URL); nowPlayingData = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ICY_METADATA).replaceAll("StreamTitle", "").replaceAll("[=,';]+", ""); mmr.release(); return null; } @Override protected void onPostExecute(String result) { nowPlaying.setText(nowPlayingData); } } private void processPhoneListenerPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, 121); } } public boolean isNetworkAvailable() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = null; if (cm != null) { networkInfo = cm.getActiveNetworkInfo(); } return networkInfo != null && networkInfo.isConnectedOrConnecting(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == 121) { if (!(grantResults[0] == PackageManager.PERMISSION_GRANTED)) { Toast.makeText(getApplicationContext(), "Permission not granted.\nWe can't pause music when phone ringing.", Toast.LENGTH_LONG).show(); } } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } @Override public void onBackPressed() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", (dialog, id) -> { if (getIsPlaying()) { stop(); } System.exit(0); }) .setNegativeButton("No", (dialog, id) -> dialog.cancel()); AlertDialog alert = builder.create(); alert.show(); } private void setIsPlaying(boolean status) { SharedPreferences.Editor editor = getApplicationContext().getSharedPreferences("isPlaying", MODE_PRIVATE).edit(); editor.putBoolean("isPlaying", status); editor.apply(); } private boolean getIsPlaying() { SharedPreferences prefs = getApplicationContext().getSharedPreferences("isPlaying", MODE_PRIVATE); return prefs.getBoolean("isPlaying", false); } private void play() { setIsPlaying(true); Intent servicePlayIntent = new Intent(this, MyService.class); servicePlayIntent.putExtra("playStop", "play"); startService(servicePlayIntent); playStop.setImageResource(R.drawable.ic_pause); Toast.makeText(getApplicationContext(), "Loading ...", Toast.LENGTH_LONG).show(); } private void stop() { setIsPlaying(false); Intent serviceStopIntent = new Intent(this, MyService.class); serviceStopIntent.putExtra("playStop", "stop"); startService(serviceStopIntent); playStop.setImageResource(R.drawable.ic_play); Toast.makeText(getApplicationContext(), "Stop Radio...", Toast.LENGTH_LONG).show(); } @Override protected void onStop() { super.onStop(); } @Override protected void onDestroy() { stopService(new Intent(getApplicationContext(), MyService.class)); unregisterReceiver(broadcastReceiver); super.onDestroy(); } }
OnBoardingAdapter
public class OnBoardingAdapter extends PagerAdapter { Context context; LayoutInflater layoutInflater; public OnBoardingAdapter(Context context) { this.context = context; } int titles[] = { R.string.title1, R.string.title2, R.string.title3, R.string.title4 }; int subtitles[] = { R.string.subtitle1, R.string.subtitle2, R.string.subtitle3, R.string.subtitle4 }; int images[] = { R.drawable.on_boarding_vector_1, R.drawable.on_boarding_vector_2, R.drawable.on_boarding_vector_3, R.drawable.on_boarding_vector_4 }; int bg[] = { R.drawable.bg1, R.drawable.bg2, R.drawable.bg3, R.drawable.bg4 }; @Override public int getCount() { return titles.length; } @Override public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { return view == (ConstraintLayout) object; } @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); View v = layoutInflater.inflate(R.layout.slide,container,false); ImageView image = v.findViewById(R.id.slideImg); TextView title = v.findViewById(R.id.sliderTitle); TextView subtitle = v.findViewById(R.id.sliderSubtitle); ConstraintLayout layout = v.findViewById(R.id.sliderLayout); image.setImageResource(images[position]); title.setText(titles[position]); subtitle.setText(subtitles[position]); layout.setBackgroundResource(bg[position]); container.addView(v); return v; } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { container.removeView((ConstraintLayout) object); } }
崩溃排查与修复方案
1. 修复SplashScreen重复加载布局问题
SplashScreen的onCreate中连续调用了两次setContentView(R.layout.activity_splash_screen);,这会导致视图初始化异常,删除其中一次即可。
2. 修正引导页数量不匹配问题
你提到引导页是3个,但OnBoardingAdapter中数组长度为4,同时dotsFunction创建了4个指示器点,页面切换逻辑中判断currentPosition <= 2,会引发索引越界:
- 将OnBoardingAdapter中的titles、subtitles、images、bg数组元素数量改为3个
- 修改dotsFunction中的
dots = new TextView[3];,确保指示器数量与页面数量一致
3. 检查SaveState类实现
SaveState负责保存引导页状态,若SharedPreferences读写逻辑错误会导致跳转异常,确保其实现正确:
public class SaveState { private SharedPreferences prefs; private String key; public SaveState(Context context, String key) { this.key = key; prefs = context.getSharedPreferences("OnBoardingPrefs", Context.MODE_PRIVATE); } public int getState() { return prefs.getInt(key, 0); } public void setState(int state) { prefs.edit().putInt(key, state).apply(); } }
4. 核对DashboardActivity视图ID
检查activity_dashboard.xml中所有ImageView的ID是否与代码中findViewById的ID完全一致,避免空指针异常。
5. 确认清单文件Activity注册
确保所有Activity在AndroidManifest.xml中正确注册,且主Activity设置为DashboardActivity:
<activity android:name=".DashboardActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".OnBoarding" /> <activity android:name=".SplashScreen" /> <activity android:name=".RadioActivity" />
内容的提问来源于stack exchange,提问作者KURONICZ STUDIO
相关产品推荐
相关产品推荐

