android - 尝试实现多语言支持时应用程序崩溃

标签 android multilingual

我正在尝试为我的应用实现多语言支持。现在我所做的只是复制我的“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/

相关文章:

android - 如何在 ionnic 和 android 上使用 websockets?

android - 我想通过触摸按钮来固定 Scrollview 吗?

android - 我在从下载管理器中选择文档文件时遇到 IllegalArgumentException,这只发生在 oreo

mysql - 将不同语言的post表的2个相同id存储到数据库中

django - Django 平面页面(或多语言 ng)的可逆命名 URL?

java - 不幸的是MyApp已停止。我该如何解决?

android - 如何防止 Android Cordova 应用程序中的水平滚动?

php - 如何在 htaccess Apache 中将/en/file.php 翻译成 file.php?lang=en

database - 使用 Laravel 进行多语言数据库管理

php - 多语言网站问题