android:findViewById从另一个类访问时返回NULL

时间:2013-07-30 06:10:23

标签: android findviewbyid

我有一个MainActivity.class,我在其上执行setContentView,这里是我以前使用的三个变量

    EditText labelText = (EditText) findViewById(R.id.label_field);
    EditText phoneText = (EditText) findViewById(R.id.phone_field);
    Spinner deviceTypeSpinner = (Spinner) findViewById(R.id.device_type_spinner);
    Button registerButton = (Button) findViewById(R.id.register_button)

现在,我有一个单独的类来扩展异步任务,我试图从异步任务(位于另一个文件中的类)修改上述字段。

为了做到这一点,我将活动的上下文传递给异步任务并执行以下步骤

            MainActivity activity = (MainActivity)context;
            Button buttonRegister =(Button)activity.findViewById(R.id.register_button);
            EditText labelText = (EditText)activity.findViewById(R.id.label_field);

            buttonRegister.setEnabled(true);
            labelText.setFocusable(true);

但是buttonRegister返回null并且应用程序崩溃了,任何人都可以告诉我哪里出错了,

  java.lang.NullPointerException
    at        com.yantranet.minixagent.requests.DeviceCreateRequest$1.onClick(DeviceCreateRequest.java:237)
    at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4895)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
    at dalvik.system.NativeStart.main(Native Method)

4 个答案:

答案 0 :(得分:2)

  

但是buttonRegister返回null并且应用程序崩溃,任何人都可以   告诉我哪里出错了,

我看不到你在哪里打电话

setContentView(<layout>);

方法。没有它,它总是返回 NPE ,因为此方法关注指定布局中所有UI实例的实体化。在使用

初始化小部件之前,必须始终调用它
findViewById(<id>);

由于你在另一个类中调用它,它将无法工作(类对你在其他类中所做的事情一无所知)。你需要:

  • 通过一些构造函数传递小部件
  • 更改应用程序逻辑(很可能未正确指定)

答案 1 :(得分:1)

如果您正在传递正确的活动上下文,那么它应该可以工作,但我不希望将上下文传递给另一个类,因为它与活动无关。您可以使用以下设计。

  1. 使用异步类注册侦听器
  2. 在活动中实施该监听器
  3. 异步任务完成后,它将调用该侦听器
  4. 活动将在侦听器执行时改变UI。

答案 2 :(得分:1)

您无法修改doInBackgroud()中的布局元素。

class MyAsync extends AsyncTask<String, Integer, String>{

@Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
    // TODO Auto-generated method stub
    return null;
}
@Override
protected void onPostExecute(String result) {
    // TODO Auto-generated method stub
    super.onPostExecute(result);
}

}

您可以使用onPreExecute()onPostExecute(String result)修改布局元素。

现在,我建议你在调用AsyncClass execute的同一个类中覆盖onPostExecute()。 例如: -

new MyLoadAsync(Inbox.this){
            private ProgressDialog pDialog;
            @Override
            protected void onPreExecute() {
                pDialog = new ProgressDialog(Inbox.this);//////////
                pDialog.setMessage("Loading... Please wait...");
                pDialog.setIndeterminate(false);
                pDialog.setCancelable(false);
                pDialog.show();
                super.onPreExecute();
            }
            @Override
            protected void onPostExecute(JSONArray result) {
                pDialog.dismiss();
                if(result!=null){

                }
                super.onPostExecute(result);
            }


        }.execute("your_param");

所以,在这里你可以访问你的布局参数。

答案 3 :(得分:1)

这不是一个好方法,但是如果你想访问其他活动的小部件,那么你应该为它设置getter setter。

//In you mainActivity
public Button getRegisterButton()
{
     //Return register button here.
     return btn;
}
public EditText getFieldEditText()
{
      //Return editText here;
      return eText;
}

您想要此视图的代码。

//在当前活动中。

            MainActivity activity = (MainActivity)context;
            Button buttonRegister =activity.getRegisterButton();
            EditText labelText = activity.getFieldEditText();
         if(buttonRegister != null)
         {
            buttonRegister.setEnabled(true);
         }
         if(labelText != null)
         {
            labelText.setFocusable(true);
         }

希望这会有所帮助。