我正在尝试为我的应用实现多语言支持。现在我所做的只是复制我的“values”文件夹并将其粘贴为“values-ru”,以支持俄语。我什至没有更改字符串值,只是保持原样。然后我将模拟器切换为俄语并安装了该应用程序。但是一旦我运行它 - 它崩溃了,我在 LogCat 中收到这些错误消息:
07-11 17:39:45.054: E/AndroidRuntime(19336): FATAL EXCEPTION: main
07-11 17:39:45.054: E/AndroidRuntime(19336): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mycompany.myapp/com.mycompany.myapp.fragments.Fragment_Main}: java.lang.NullPointerException
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.ActivityThread.access$600(ActivityThread.java:123)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.os.Handler.dispatchMessage(Handler.java:99)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.os.Looper.loop(Looper.java:137)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.ActivityThread.main(ActivityThread.java:4424)
07-11 17:39:45.054: E/AndroidRuntime(19336): at java.lang.reflect.Method.invokeNative(Native Method)
07-11 17:39:45.054: E/AndroidRuntime(19336): at java.lang.reflect.Method.invoke(Method.java:511)
07-11 17:39:45.054: E/AndroidRuntime(19336): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-11 17:39:45.054: E/AndroidRuntime(19336): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-11 17:39:45.054: E/AndroidRuntime(19336): at dalvik.system.NativeStart.main(Native Method)
07-11 17:39:45.054: E/AndroidRuntime(19336): Caused by: java.lang.NullPointerException
07-11 17:39:45.054: E/AndroidRuntime(19336): at com.mycompany.myapp.fragments.Fragment_Main.onCreate(Fragment_Main.java:101)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.Activity.performCreate(Activity.java:4465)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
07-11 17:39:45.054: E/AndroidRuntime(19336): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
07-11 17:39:45.054: E/AndroidRuntime(19336): ... 11 more
为什么会这样?我该如何解决?
编辑
这是我的 Fragment_Main 的代码:
package com.mycompany.myapp.fragments;
import java.util.Locale;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import com.mycompany.myapp.activities.Activity_Preferences;
import com.mycompany.myapp.R;
public class Fragment_Main extends FragmentActivity implements
ActionBar.TabListener/*, Fragment_Picker_Time.OnTimeDialogListener*/ {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
/*public int picked_hour;
public int picked_minute;*/
public int tab_position;
MenuItem action_button;
Menu menu;
SharedPreferences preferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
getBaseContext();
int actionBarTitleId = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
if (actionBarTitleId > 0) {
TextView title = (TextView) findViewById(actionBarTitleId);
if (title != null) {
title.setTextColor(Color.parseColor("#4d4a47"));
title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC), Typeface.BOLD_ITALIC);
}
}
// Set up the action bar.
final ActionBar actionBar = getActionBar();
//actionBar.setTitle("another title");
//actionBar.setSubtitle("my scheduler");
actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.app_bg));
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
setTab_position(tab.getPosition());
//change_action_button_icon(tab.getPosition());
//Toast.makeText(this, "Selected tab: "+tab.getPosition(), Toast.LENGTH_SHORT).show();
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
//TODO
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
//TODO
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = null;
switch (position)
{
case 0:
fragment = new Fragment_Trips();
break;
case 1:
fragment = new Fragment_Master_List();
break;
}
return fragment;
}
@Override
public int getCount() {
// Show 2 total pages.
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_tab_trips).toUpperCase(l);
case 1:
return getString(R.string.title_tab_master_list).toUpperCase(l);
}
return null;
}
}
public void change_action_button_icon(int tab_position)
{
switch(tab_position)
{
case 0:
action_button.setIcon(R.drawable.ico_add_group);
break;
case 1:
action_button.setIcon(getResources().getDrawable(R.drawable.ico_add_message));
break;
}
invalidateOptionsMenu();
}
public int getTab_position() {
return tab_position;
}
public void setTab_position(int tab_position) {
this.tab_position = tab_position;
}
public MenuItem getAction_button() {
return action_button;
}
public void setAction_button(MenuItem action_button) {
this.action_button = action_button;
}
// -----BEGIN OPTIONS MENU-----//
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.options_menu, menu);
super.onCreateOptionsMenu(menu);
}
// ACTIONS OF OPTION MENU
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//Play a sound when an option is selected
//SoundUtility.getInstance(ActivityListCatalog.this).playPositive();
// Check which button in the menu was clicked and open a corresponding activity
// or perform a requested method
switch(item.getItemId())
{
case R.id.opt_menu_preferences:
Intent preferences = new Intent(getBaseContext(), Activity_Preferences.class);
startActivity(preferences);
break;
case R.id.opt_menu_options: // About activity
//Intent openAbout = new Intent(ActivityListCatalog.this, About.class);
//startActivity(openAbout);
break;
case R.id.opt_menu_help: // user cancels
break;
}
return super.onOptionsItemSelected(item);
}
//-----END OPTIONS MENU-----//
最佳答案
我很确定问题出在 language has a greater precedence than other qualifiers在根据提供资源表决定使用哪些替代资源时(请参阅最佳匹配算法 here)。
因此,如果您将资源放在 values-ru
中,那么例如 values-v14
中的资源将不会被使用。在这种情况下,Action Bar 可能因此配置错误(因为 values
中的某些资源假定设备具有较低的 API 级别,并在 values-vxx
)。
您应该只将 strings.xml
复制到 values-ru
(以及您确实想要自定义的其他资源),而不是整个文件夹。
关于android - 尝试实现多语言支持时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24700707/