我的应用程序在api 24及更高版本上运行,但在api 19下崩溃。 问题似乎出在OnCreate方法的setContentView行上。
我试图更改XML文件中的所有API 21+功能,但无济于事。 还尝试放入multidex,但没有用。
这是在setContentView崩溃的活动:
package com.idan.idanzimbler.epiclogin.view;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.idan.idanzimbler.epiclogin.R;
import com.idan.idanzimbler.epiclogin.controller.FillSeriesListFromFireBaseBySearchTask;
import com.idan.idanzimbler.epiclogin.controller.FillSeriesListFromFireBaseBySuggestionsTask;
import com.idan.idanzimbler.epiclogin.controller.FillSeriesListFromFireBaseTask;
import com.idan.idanzimbler.epiclogin.controller.TvSeriesFavoriteList;
import com.idan.idanzimbler.epiclogin.controller.TvSeriesHomeList;
import com.idan.idanzimbler.epiclogin.controller.UsersBookmarks;
import com.idan.idanzimbler.epiclogin.modle.TvSeries;
import com.google.firebase.auth.FirebaseAuth;
import com.squareup.picasso.Picasso;
import java.util.Locale;
public class HomeActivity extends AppCompatActivity implements AbsListView.OnScrollListener {
public static final String INTENT_FLAG = "flag";
public static final int FIRST_ENTER = 1;
//public static final int REBUILD = 2;
public static final int RECOMMENDATION_ENTER = 2;
ExpandableListView list;
EditText searchEt;
ProgressBar progressBar;
HomeActivity context;
ImageView questionmarkHomeBtn;
boolean isInSearchMode;
boolean isInRecommendationMode;
TextView homeToolbarTitleTV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
loadLocale();
Toolbar toolbar = findViewById(R.id.homeToolbar);
toolbar.setTitle("");
homeToolbarTitleTV = findViewById(R.id.home_titleTV);
setSupportActionBar(toolbar);
context = this;
isInSearchMode = false;
isInRecommendationMode = false;
progressBar = findViewById(R.id.home_progressbar);
questionmarkHomeBtn = findViewById(R.id.home_questionmark_btn);
list = findViewById(R.id.home_series_list);
searchEt = findViewById(R.id.home_search_et);
progressBar.setVisibility(View.VISIBLE);
TvSeriesHomeList.getInstance().clear();
TvSeriesFavoriteList.getInstance().clear();
TvSeriesFavoriteList.getInstance().initializeSeriesList();
UsersBookmarks.getInstance().initializeBookmarks();
Bundle b = getIntent().getExtras();
int flag = 1;
if (b != null) flag = b.getInt(INTENT_FLAG);
if (flag == FIRST_ENTER) {
new FillSeriesListFromFireBaseTask(this, list).execute();
} else if (flag == RECOMMENDATION_ENTER) {
progressBar.setVisibility(View.VISIBLE);
isInRecommendationMode = true;
homeToolbarTitleTV.setText(getString(R.string.recommendation));
new FillSeriesListFromFireBaseBySuggestionsTask(context, list).execute();
}
list.setOnScrollListener(this);
list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
TvSeriesFavoriteList favorites = TvSeriesFavoriteList.getInstance();
TvSeries series = TvSeriesHomeList.getInstance().getSeries().get(position);
if (favorites.contains(series.getId())) {
favorites.remove(series.getId());
ImageView star = view.findViewById(R.id.series_list_fav_iv);
Picasso.get().load(R.drawable.emptystar).fit().into(star);
Toast.makeText(getApplicationContext(), "Removed from favorites", Toast.LENGTH_SHORT).show();
} else if (favorites.canAdd(series)) {
favorites.add(series);
ImageView star = view.findViewById(R.id.series_list_fav_iv);
Picasso.get().load(R.drawable.filledstar).fit().into(star);
Toast.makeText(getApplicationContext(), "Added to favorites", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Maximum of 5 series can be added to favorites", Toast.LENGTH_SHORT).show();
}
return true;
}
});
searchEt.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String searchString = s.toString().trim();
if (searchString.isEmpty()) {
isInSearchMode = false;
TvSeriesHomeList.getInstance().clear();
new FillSeriesListFromFireBaseTask(context, list).execute();
} else {
isInSearchMode = true;
new FillSeriesListFromFireBaseBySearchTask(context, list, searchString).execute();
}
}
});
questionmarkHomeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(HomeActivity.this);
builder.setCancelable(true);
builder.setTitle(getString(R.string.how_to_use));
builder.setMessage(getString(R.string.home_fav_bookmark_explain));
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.show();
}
});
}
@Override
protected void onResume() {
super.onResume();
loadLocale();
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (!isInSearchMode && !isInRecommendationMode) {
switch (view.getId()) {
case R.id.home_series_list:
final int lastItem = firstVisibleItem + visibleItemCount;
if (lastItem == totalItemCount) {
if (TvSeriesHomeList.getInstance().getPreLast() != lastItem) {
TvSeriesHomeList.getInstance().incrementPage();
new FillSeriesListFromFireBaseTask(this, list).execute();
TvSeriesHomeList.getInstance().setPreLast(lastItem);
}
}
}
}
}
public ProgressBar getProgressBar() {
return progressBar;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.profilemenu:
startActivity(new Intent(this, ProfileActivity.class));
break;
case R.id.favoritesmenu:
startActivity(new Intent(this, FavoritesActivity.class));
break;
case R.id.aboutmenu:
startActivity(new Intent(this, AboutActivity.class));
break;
case R.id.signoutmenu:
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
break;
case R.id.recommendationmenu:
TvSeriesHomeList.getInstance().clear();
progressBar.setVisibility(View.VISIBLE);
isInRecommendationMode = true;
new FillSeriesListFromFireBaseBySuggestionsTask(context, list).execute();
homeToolbarTitleTV.setText(getString(R.string.recommendation));
break;
case R.id.homemenu:
if (isInRecommendationMode) {
isInRecommendationMode = false;
TvSeriesHomeList.getInstance().clear();
new FillSeriesListFromFireBaseTask(this, list).execute();
}
homeToolbarTitleTV.setText(getString(R.string.home));
break;
case R.id.rateusmenu:
try{
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=com.idan.idanzimbler.epiclogin")));
}catch (ActivityNotFoundException e){
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=com.idan.idanzimbler.epiclogin")));
}
}
return true;
}
@Override
public void onBackPressed() {
if (!searchEt.getText().toString().isEmpty()) {
searchEt.setText("");
} else if (isInRecommendationMode) {
isInRecommendationMode = false;
TvSeriesHomeList.getInstance().clear();
new FillSeriesListFromFireBaseTask(this, list).execute();
}else {
super.onBackPressed();
}
}
public void setLocale(String lang) {
Locale locale = new Locale(lang,"US");
if(lang.equals("he")){
locale = new Locale(lang,"IL");
}
else if(lang.equals("ar")){
locale = new Locale(lang,"JO");
}
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());
SharedPreferences.Editor editor = getSharedPreferences("Settings" ,MODE_PRIVATE).edit();
editor.putString("My_Lang",lang);
editor.apply();
}
public void loadLocale(){
SharedPreferences prefs = getSharedPreferences("Settings",Activity.MODE_PRIVATE);
String language = prefs.getString("My_Lang", "");
setLocale(language);
}
}
XML文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.HomeActivity">
<EditText
android:id="@+id/home_search_et"
android:layout_width="301dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="14dp"
android:layout_weight="1"
android:ems="10"
android:hint="@string/enter_tv_series_name"
android:inputType="textPersonName"
app:backgroundTint="@color/common_google_signin_btn_text_dark_focused"
app:layout_constraintBottom_toTopOf="@+id/home_series_list"
app:layout_constraintEnd_toStartOf="@+id/home_questionmark_btn"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appBarLayout"
/>
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"
app:layout_constraintBottom_toTopOf="@+id/home_search_et"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.v7.widget.Toolbar
android:id="@+id/homeToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:contentInsetStart="0dp"
android:contentInsetLeft="0dp"
android:contentInsetEnd="0dp"
android:contentInsetRight="0dp"
android:elevation="2dp"
android:gravity="end"
app:contentInsetEnd="0dp"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetStart="0dp"
app:popupTheme="@style/AppTheme.PopupOverlay"
tools:targetApi="lollipop">
<TextView
android:id="@+id/home_titleTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/home"
android:textColor="@color/common_google_signin_btn_text_dark_default"
android:textSize="25sp"
android:textStyle="bold" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<ExpandableListView
android:id="@+id/home_series_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="4dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_search_et" />
<ProgressBar
android:id="@+id/home_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:indeterminateDrawable="@drawable/blackprogressbar"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/home_series_list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/home_questionmark_btn"
android:layout_width="34dp"
android:layout_height="24dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="@+id/home_search_et"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/home_search_et"
app:srcCompat="@drawable/questionmarklogo"
android:contentDescription="TODO" />
</android.support.constraint.ConstraintLayout>
运行:
V/FA: Activity paused, time: 2504321
V/FA: onActivityCreated
D/FA: Logging event (FE): user_engagement(_e), Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=11068, firebase_screen_class(_sc)=MainActivity, firebase_screen_id(_si)=-8684354233398184439}]
W/dalvikvm: JNI WARNING: NewStringUTF input is not valid Modified UTF-8: illegal start byte 0xf0
string: 'en_Latn_US_�_US'
in Llibcore/icu/ICU;.addLikelySubtags:(Ljava/lang/String;)Ljava/lang/String; (NewStringUTF)
I/dalvikvm: "main" prio=5 tid=1 NATIVE
| group="main" sCount=0 dsCount=0 obj=0xa4d56bd8 self=0xb7e34eb0
| sysTid=3387 nice=0 sched=0/0 cgrp=apps handle=-1216573376
| state=R schedstat=( 1431490769 212065377 2672 ) utm=91 stm=51 core=1
I/dalvikvm: #00 pc 000bd936 /system/lib/libdvm.so (dvmDumpNativeStack(DebugOutputTarget const*, int)+86)
#01 pc 00098513 /system/lib/libdvm.so (dvmDumpThreadEx(DebugOutputTarget const*, Thread*, bool)+1155)
#02 pc 00098806 /system/lib/libdvm.so (dvmDumpThread(Thread*, bool)+86)
#03 pc 0004d3ff /system/lib/libdvm.so (ScopedCheck::checkUtfString(char const*, bool)+271)
#04 pc 0004e2ad /system/lib/libdvm.so (ScopedCheck::check(bool, char const*, ...)+1437)
#05 pc 00052927 /system/lib/libdvm.so
#06 pc 000204be /system/lib/libjavacore.so
#07 pc 0002a4ab /system/lib/libdvm.so (dvmPlatformInvoke+79)
at libcore.icu.ICU.addLikelySubtags(Native Method)
I/dalvikvm: at android.text.TextUtils.getLayoutDirectionFromLocale(TextUtils.java:1740)
at android.content.res.Configuration.setLayoutDirection(Configuration.java:1295)
at android.content.res.Configuration.updateFrom(Configuration.java:820)
at android.content.res.Resources.updateConfiguration(Resources.java:1557)
at android.content.res.Resources.updateConfiguration(Resources.java:1511)
at android.support.v7.widget.ResourcesWrapper.updateConfiguration(ResourcesWrapper.java:232)
at android.content.res.Resources.<init>(Resources.java:202)
at android.content.res.Resources.<init>(Resources.java:179)
at android.support.v7.widget.ResourcesWrapper.<init>(ResourcesWrapper.java:48)
at android.support.v7.widget.TintResources.<init>(TintResources.java:35)
at android.support.v7.widget.TintContextWrapper.<init>(TintContextWrapper.java:101)
at android.support.v7.widget.TintContextWrapper.wrap(TintContextWrapper.java:69)
at android.support.v7.widget.AppCompatEditText.<init>(AppCompatEditText.java:69)
at android.support.v7.widget.AppCompatEditText.<init>(AppCompatEditText.java:65)
at android.support.v7.app.AppCompatViewInflater.createEditText(AppCompatViewInflater.java:192)
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:114)
at android.support.v7.app.AppCompatDelegateImpl.createView(AppCompatDelegateImpl.java:1266)
at android.support.v7.app.AppCompatDelegateImpl.onCreateView(AppCompatDelegateImpl.java:1316)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:684)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at com.idan.idanzimbler.epiclogin.view.HomeActivity.onCreate(HomeActivity.java:58)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
E/dalvikvm: VM aborting
A/libc: Fatal signal 6 (SIGABRT) at 0x00000d3b (code=-6), thread 3387 (mbler.
Application terminated.
答案 0 :(得分:1)
stacktrace似乎指示读取当前资源配置时出现问题(无论您的语言环境是否为RTL)。
查看活动代码,您正在修改应用程序使用的语言环境,而不是使用可以解释问题的电话语言环境。您的活动实际上将经过onCreate
两次。第一次可能是毫无问题地扩展了XML视图,但是一旦您设置了新的配置(通过调用loadLocale()
),Activity将被销毁并重新创建,它将再次执行onCreate()
使用新的配置。这是您的应用程序崩溃的时候。
我认为,问题很可能是setLocale()
方法中的问题,无法正确完成Configuration的更改,新的API可以使用默认值,而旧的API只会崩溃。
即使我不建议在应用程序中修改语言环境,这里还是有关在Android应用程序中修改语言环境的更多信息:
https://proandroiddev.com/change-language-programmatically-at-runtime-on-android-5e6bc15c758
根据所支持的API版本,可以使用不同的方法。
他用来更改配置的方法如下:
private static Context updateResources(Context context, Locale locale) {
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = new Configuration(res.getConfiguration());
if (Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
context = context.createConfigurationContext(config);
} else {
config.locale = locale;
res.updateConfiguration(config, res.getDisplayMetrics());
}
return context;
}