0

这个问题让我怀疑自己的理智。我想我遇到了一个 android 错误,我需要解决 NumberFormat.getIntegerInstance().format 的替代解决方案。

我在获取格式化数字以在 TextView 中显示时遇到问题 这是一个间歇性问题,但无法可靠地重现。

我有一种方法可以在每次通过片段中的回调事件选择微调器项目时计算余额。有 6 个微调器,选择哪个并不重要

有时需要单击 30 或 40 次(在微调器上进行选择)才能出现问题,有时只需单击 10 或 12 次。该问题与实际值完全无关,并且 calcBalance 方法总是返回一个格式化的整数。只是有时该整数在 TextView 中显示为空白文本。

问题是 setText 方法正在工作,它只是不显示的数字。

一旦问题出现,几乎每次选择都会发生在横向和纵向之间切换似乎可以解决问题,但它会重新开始

calcBalance 方法如下所示

public String calcBalance() {
    int balance = 90000000;
    for(int i = 0; i < this.cars.size(); i++){
        balance = balance - this.cars.get(i).getDriver().getPrice();
        balance = balance - this.cars.get(i).getChassis().getPrice();
        balance = balance - this.cars.get(i).getEngine().getPrice();
        Log.i("@@@@", "Calculating balance: " + balance);
    }
    return NumberFormat.getIntegerInstance().format(balance);
}

使用调试消息调用此平衡的方法如下所示

    @Override
    public void onBalanceChanged(int position, CarModel car) {
//      Try to change the car but if it has not already been added then add it instead using outOfBounds
//      exception to check if item exists
        mi ++;
        try {
            mTeam.cars.set(position, car);
        }catch(java.lang.IndexOutOfBoundsException e){
            mTeam.cars.add(car);
        }
        if (mTvBalance == null){
            mTvBalance = (TextView) findViewById(R.id.lblBalance);
        }
        String balance = mTeam.calcBalance();
        Util.log_debug_message("Setting text Balance is " + balance);
        String balance_text = mi + " Available Balance: $" + balance;  
        Util.log_debug_message("Balance text is " + balance_text);
        mTvBalance.setText(balance_text);
    }

一个示例日志输出表明我正在设置的文本的值是

余额文本为 25 可用余额:10,000,000 美元

然而文本视图只显示

25 可用余额:

数字 25 只是我调试的一部分,以证明 TextView.setText 实际上已被设置,而只是未显示的数字。

导致 TextView 仅显示没有值的文本的日志输出(包括上面的示例如下

W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@4514fe58
I/@@@@    ( 1249): Calculating balance: 45000000
I/@@@@    ( 1249): Calculating balance: 0
D/QuizApp ( 1249): Setting text Balance is 0
D/QuizApp ( 1249): Balance text is 24 Available Balance: $0
W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@450f3ec0
I/@@@@    ( 1249): Calculating balance: 45000000
I/@@@@    ( 1249): Calculating balance: 10000000
D/QuizApp ( 1249): Setting text Balance is 10,000,000
D/QuizApp ( 1249): Balance text is 25 Available Balance: $10,000,000
W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@4517e3d0
W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@451c4b70
W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@4513fef8
I/@@@@    ( 1249): Calculating balance: 45000000
I/@@@@    ( 1249): Calculating balance: 13000000
D/QuizApp ( 1249): Setting text Balance is 13,000,000
D/QuizApp ( 1249): Balance text is 26 Available Balance: $13,000,000
W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@45115e48

以及我在 TextView 中获得正确文本集的时间的一些日志输出

I/@@@@    ( 1249): Calculating balance: 45000000
I/@@@@    ( 1249): Calculating balance: 0
D/QuizApp ( 1249): Setting text Balance is 0
D/QuizApp ( 1249): Balance text is 8 Available Balance: $0
W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@45020d10
I/@@@@    ( 1249): Calculating balance: 55000000
I/@@@@    ( 1249): Calculating balance: 10000000
D/QuizApp ( 1249): Setting text Balance is 10,000,000
D/QuizApp ( 1249): Balance text is 9 Available Balance: $10,000,000
W/InputManagerService(   59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@44f85c58
I/@@@@    ( 1249): Calculating balance: 55000000
I/@@@@    ( 1249): Calculating balance: 20000000
D/QuizApp ( 1249): Setting text Balance is 20,000,000
D/QuizApp ( 1249): Balance text is 10 Available Balance: $20,000,000

我只能假设我有时会从调用返回一些不可打印的字符NumberFormat.getIntegerInstance().format

我在模拟器和运行从 2.2 到 4.1 的不同操作系统的 3 部不同手机上遇到了这个问题。

那么,我必须以何种方式格式化数字才能可靠地显示在 TextView 中?

更新完整的片段活动

public class NewTeamFragmentActivity extends SherlockFragmentActivity implements TabListener, OnBalanceChangedListener, OnTeamDataChangedListener{

    static final int NUM_ITEMS = 3;
    private ViewPager mPager;
    private NewTeamSwipeAdapter mAdapter;
    private TeamModel mTeam;
    private TextView mTvBalance;
    private int mi = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_team);
        // Show the Up button in the action bar.
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setNavigationMode( ActionBar.NAVIGATION_MODE_TABS );
        mAdapter = new NewTeamSwipeAdapter(getSupportFragmentManager());

        mPager = (ViewPager)findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);
        mPager.setOnPageChangeListener(
                new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        // When swiping between pages, select the
                        // corresponding tab.
                        getSupportActionBar().setSelectedNavigationItem(position);
                    }
                });
        setupTabs();
        setupModels();
        createFragments();
    }

    private void createFragments() {
        NewTeamFragment teamFragment = new NewTeamFragment();
        Bundle arguments = new Bundle();
        FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
        trans.replace(R.id.new_team_fragment_container, teamFragment);
        trans.commit();
    }

    private void setupModels() {
        mTeam = new TeamModel();
    }

    private void setupTabs() {
        add_tab("Car 1");
        add_tab("Car 2");
        add_tab("Submit Team");
    }

    private void add_tab(String tabText) {
        Tab tab = getSupportActionBar().newTab();
        tab.setText(tabText);
        tab.setTabListener(this);
        getSupportActionBar().addTab(tab);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getSupportMenuInflater().inflate(R.menu.activity_new_team, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            // This ID represents the Home or Up button. In the case of this
            // activity, the Up button is shown. Use NavUtils to allow users
            // to navigate up one level in the application structure. For
            // more details, see the Navigation pattern on Android Design:
            //
            // http://developer.android.com/design/patterns/navigation.html#up-vs-back
            //
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    public static class NewTeamSwipeAdapter extends FragmentPagerAdapter {

        public NewTeamSwipeAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            Fragment return_frag = null;
            if (position < 2){
                Bundle arguments = new Bundle();
                arguments.putInt(KeyConstants.CAR_ID_KEY, position);
                NewCarFragment fragment = new NewCarFragment();
                fragment.setArguments(arguments);
                return_frag = fragment;
            } else if (position == 2) {
                SubmitTeamFragment fragment = new SubmitTeamFragment();
                return_frag = fragment;
            }
            return return_frag;
        }

        @Override
        public CharSequence getPageTitle (int position){
            CharSequence title = "Unknown!";
            if (position < 2){
                title = "Car " + (position + 1);
            }else if(position == 2){
                title = "Submit Team";
            }
            return title;
        }
    }
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        mPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onBalanceChanged(int position, CarModel car) {
//      Try to change the car but if it has not already been added then add it instead using outOfBounds
//      exception to check if item exists
        mi ++;
        try {
            mTeam.cars.set(position, car);
        }catch(java.lang.IndexOutOfBoundsException e){
            mTeam.cars.add(car);
        }
        if (mTvBalance == null){
            mTvBalance = (TextView) findViewById(R.id.lblBalance);
        }
        String balance = mTeam.calcBalance();
        Util.log_debug_message("Setting text Balance is " + balance);
        String balance_text = mi + " Available Balance: $" + balance;  
        Util.log_debug_message("Balance text is " + balance_text);
        mTvBalance.setText(balance_text);
    }

    @Override
    public void onTeamDataChanged(TeamModel mTeam) {
        // TODO Auto-generated method stub
        if (this.mTeam == null){
            this.mTeam = mTeam;
        }else{
            this.mTeam.setTeamName(mTeam.getTeamName());
        }
    }

}

更新 -这绝对是 NumberFormat.getIntegerInstance() 的问题

Integer.toString(balance); 不会造成任何问题。那么我怎样才能可靠地用逗号格式化整数呢?

4

1 回答 1

1

我很确定android中有一个错误。查看NumberFormat.getIntegerInstance()http://developer.android.com/reference/java/text/NumberFormat.html)的文档,有提到这个方法不应该被调用太多次有点包裹在一个更好的性能获得整数实例一次,将其设置为成员变量并重新使用它。引用

如果您正在格式化多个数字,那么获取格式并多次使用它会更有效,这样系统就不必多次获取有关本地语言和国家/地区惯例的信息。

当然是这样,但是在其他类中并没有真正提到这样的性能问题,所以我怀疑 Android 团队意识到如果调用过于频繁,这种方法可能会证明有点不可靠,但他们并不会真正做任何事情关于它。我可能会同意,如果是这种情况,那么他们为什么要这样做?由开发人员来优化代码,如果代码经过优化,那么您将不会遇到问题。

问题是我的代码根本没有优化。因为这种方法被用于同时加载的多个微调器中。

我已经重构了我的代码,并确保通过将结果分配给成员变量并且仅在成员变量为 null 并且一切看起来都不错时才调用此方法,但我感到不安的是功能并不像它可能的那样稳定,这可能会再次受到影响。

于 2013-03-02T12:15:37.273 回答