首页 > 试题广场 >

下面代码运行结果是()

[单选题]
下面代码运行结果是()
public classMainActivity extends Activity implements OnClickListener
{
   private Button mBtnLogin = (Button) findViewById(R.id.btn_login);
   private TextView mTextViewUser;
 
   @Override
   protected void onCreate(BundlesavedInstanceState)
   {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextViewUser = (TextView) findViewById(R.id.textview_user);
        mBtnLogin.setOnClickListener(this);
        new Thread()
        {
            @Override
            public void run()
            {
                mTextViewUser.setText(10);
            }
        }.start();
   }
 
   @Override
   public void onClick(View v)
   {
        mTextViewUser.setText(20);
   }
}
  • Resources$NotFoundException
  • ViewRootImpl$CalledFromWrongThreadException
  • NullPointerException
  • 运行正常,mTextViewUser 组件上显示内容为10
居然被忽悠了。。。。看题不仔细啊
发表于 2015-09-17 16:44:42 回复(0)
代码实测:
1、首先会报错NullPointerException,就是privateButton mBtnLogin = (Button) findViewById(R.id.btn_login);这个位置,要先加载了layout后才能成功获取到相应的按钮组件对象;
2、修改NullPointerException错误后再运行,报错 Resources$NotFoundException,在mTextViewUser.setText(10);这个位置(原本以为会先检查onclick方法里的setText(),但实际是run()里的setText()),要改成字符串形式;
3、修改上面的错误后再运行,报错Resources$NotFoundException,这次就轮到mTextViewUser.setText(20);这个位置了;
4、修改上面的错误后再运行,没有报错,程序成功运行,点击按钮后TextView由10变为20,说好的不能在非UI线程里更新UI组件呢?翻看别人的博客后,终于找到答案了,其实非UI线程是可以刷新UI的,前提是它要拥有自己的ViewRoot,ViewRoot是在onResume()里addview()创建的,所以是在 onResume()检查是否为UI线程,一般在onCreate()中通过子线程可以更新UI,但官方不建议这样做,因为 Android UI操作并不是线程安全的。
PS:而且,可以试下在上面代码的run()中setText()前加一句Thread.sleep(2000),先让线程休眠个2到3秒,就会报错 ViewRootImpl$CalledFromWrongThreadException,说明已经检查到在非UI线程里更新UI。
编辑于 2016-07-25 11:32:28 回复(12)
选C。Button的初始化时找不到对应的id的。id绑定应该在setContentView后执行。
编辑于 2021-12-23 12:55:38 回复(20)
干扰项很多。
A:选A说明还是了解setText(int resID),尤其是注意显示数字时,转换成字符串。否则报错Resources$NotFoundException
B:在android中,只有主线程才能修改View组件。所以出现了Handler,AsyncTask等在子线程进行耗时操作,然后在主线程中修改View。
C:只有当layout 渲染之后才能找到该layout中的view,否则报错。
发表于 2015-04-23 16:59:23 回复(14)
privateButton mBtnLogin = (Button) findViewById(R.id.btn_login);
这行代码并不会报错,只是会将该Button的值设置为null;
mBtnLogin.setOnClickListener(this);
当执行到该行代码时,由于 mBtnLogin对象的值为null,所以会报空指针
发表于 2015-10-20 17:53:15 回复(1)
在子线程中也是可以更新ui的,前提是系统还没执行到onResume方法。判断是不是UI线程的方法是在onResume中启动的!!!
发表于 2015-08-12 16:34:48 回复(7)
额,被忽悠了,没看到上面
发表于 2015-08-17 11:48:30 回复(0)
请同学们做这种题的时候要亲自在AS上运行感受, 我运行的结果如下,并且是按exception的先后顺序出来的:
1.错误:java.lang.NullPointerException, 
  原因:在setContentView方法之后能通过findViewById找到layout中的控件,我们可以官方对这个方法的解释: 
    setContentView(View, android.view.ViewGroup.LayoutParams)}
     * to set the screen content from a layout resource.  The resource will be
     * inflated, adding all top-level views to the screen.
 解决:在setContentView方法之后对Layout中的控件进行初始化
2.错误:android.content.res.Resources$NotFoundException
   原因:setText(xxx),系统会通过xxx在R文件中对应的整型Id去找资源,如果xxx是整形,就会在R文件中以xxx为目的去寻找资源,显然找不到
   解决: XXX必须为非int型数据 
   注意: 本题中有两处需要setText方法中的数据为整型需要修改哦
3. 至于他们说的不能在子线程修改UI确实有这么一说,并且如果再子线程中修改UI的话对应的exception 为:
E/AndroidRuntime(3572): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
注意: 题目中的代码并不会出现这个错误,不信, 你们可以自行运行。
有些同学会问,怎么会出现这个问题呢?其实我只是在子线程更新UI的上面加了一句SystemClock.sleep(3000); 这样让系统睡眠了。。。相当于执行了耗时操作,为什么是这样一个情况我也不清楚,如果知道的同学,希望不吝赐教。

发表于 2016-08-16 21:18:18 回复(0)
错在:mBtnLogin.setOnClickListener(this);
mBtnLogin此时为NULL
发表于 2016-08-01 17:05:13 回复(0)
这道其实是考这个用法:
setText(int rid)
int 类型 肯定找不到资源
这也是实际开发经常忽略的小问题了
记住,一定要是字符串类型
编辑于 2016-07-08 15:38:05 回复(0)
这个题我明天要跑一下,抛开button初始化不说,在oncreate中启动子线程更新UI,其实是可以实现的,也不会报错,因为UI控件的线程检测是在onresume中才执行。
编辑于 2015-07-28 00:11:16 回复(1)
这道题尼玛是晃点人用的!
把一个明显的错误暴露出来(在子线程处理UI),其实忽略了上面初始时实例了Button 的错误!!
真低级!!!!!!!!!!
发表于 2015-04-09 22:37:17 回复(4)
明白了
发表于 2022-02-08 21:14:28 回复(0)
 private Button mBtnLogin = (Button) findViewById(R.id.btn_login);//会报错
Window window=this.getWindow();//不会报错
这是为什么
发表于 2019-04-29 19:16:27 回复(0)
我选A,我还没有去测试代码,我记得的话布局还没加载出来的时候,是找不到id的,应该是NIT FOUND RESOURCE
发表于 2019-03-27 20:28:05 回复(0)
Button的初始化应该放在oncreat里面或者直接将这句Button mBtnLogin = (Button) findViewById(R.id.btn_login);放在oncreat里面作为局部变量
发表于 2018-09-15 17:27:31 回复(0)
有多少选B的请举手
发表于 2018-03-28 17:49:11 回复(0)
1楼回答的很正确, button的初始化要在视图资源加载之后
发表于 2017-08-08 15:27:34 回复(0)
 privateButton mBtnLogin = (Button) findViewById(R.id.btn_login);在此处会报空指针异常,是因为getWindow()为空,
如果将此句放在onCreate里面,setContentView上面,mBtnLogin为null,但是并不会报错,只会在setOnclick时报空指针;
发表于 2017-07-11 10:53:46 回复(0)
settext 中设置一个整数,应该会报错啊,设置整数的时候表示根据这个id去查找字符串,难道不是这样的么?
发表于 2017-05-15 22:58:41 回复(0)