java - 在处理程序上调用时, TextView 为空

标签 java android android-activity view handler

我正在尝试在 Textview 上执行 setText() (已在 onCreate() 中实例化),由 Handler 并使用 ruiOnUiTread() 但我在 Textview 上有一个 nullPointerException

问题从何而来?

我在调试中看到 activity 的实例在实例化和 setText() 之间不同,虽然我没有更改 activity 但无法实例化它与 setText() 位于同一位置。

private TextView ambianceTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ambianceTextView = findViewById(R.id.valeur_ambiance);

    StarterKillerPidroid.getInstance().startApp();
}

private final Runnable retrieveData = new Runnable() {
    public void run() {
        try {
            setText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        handlerRecup.postDelayed(retrieveData, 1000);
    }
};

public void setText(){
  runOnUiThread(new Runnable() {
     @Override
     public void run() {
        ambianceTextView.setText("test");
     }
   });
}

public void doAfterLogin() {
    handlerRecup.postDelayed(retrieveData, 10000);
}

可运行程序由 Volley 的 http 请求回调调用的函数启动

公共(public)类 StarterKillerPidroid {

void startApp() {
    //Sending a request 
    PostmanPidroid.getInstance().login();
}

public void ackLogin(Boolean isValid) {
    if (isValid) {
        ActivityMain.getInstance().doAfterLogin();
    } else {
        PostmanPidroid.getInstance().login();
    }
}

}

postman 类:

  public class Postman {
   public void login(){

        // Parameters
        String email = "test@tes";
        String password = "test";

        // Encoding the request with parameters
        JsonObjectRequest request = EncoderDecoderPidroid.getInstance()
                .encodeRequestLogin(email, password);

        // Sending the request
        sendRequest(request);
     }

     void sendRequest(StringRequest message){
         // Creating the queu if it's not create
         if (queue == null) {
               queue = Volley.newRequestQueue(context);
          }
          // Adding the request to the queue
              queue.add(message);
           }
   }

当收到成功响应时,调用此回调:

 private Response.Listener<JSONObject> callbackLogin =
            new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            ...
            StarterKillerPidroid.getInstance().ackLogin(true);
        }
    };

最佳答案

基本上,这种问题是由于实例造成的。您的 textview 实例可能未初始化。还有一件事是,直接使用处理程序来更新 UI 线程并不是一个好主意。您应该使用 FunctionalInterface 来执行此操作,而不是直接使用处理程序更新 Ui。

FunctionalInterface 对于这种情况是一个很好的方法。

A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit. From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. ... Runnable, ActionListener, Comparable are some of the examples of functional interfaces.

Java 有一个预定义的FunctionalInterface Callable。事情是这样的

public static void doDid(final Callable<Void> callable) {
    final Handler handler = new Handler();

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            try {
                callable.call();
                handler.postDelayed(this, every * repeattime);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }, every * tempvalue);
}

并以这种方式使用它来更新 UI

 doDid(new Callable<Void>() {
                    @Override
                    public Void call() {
                         textView.setText("Your text");
                        return null;
                    }
                });

有一个适用于 Android 的开源库,在这种情况下它的工作方式就像一个魅力,称为 Predictor。您可以从here下载并导入到您的项目中。您还可以在此项目中做出贡献,以挽救许多开发人员的生命。

你想看看预测器如何做到这一点吗?

 Predictor.every(3).second().doDid(new Job<Void>() {
                    @Override
                    public Void run() {
                        textView.setText("Your text");
                        return null;
                    }
                });

你可以用预测器做什么?

Predictor 为您提供了几种处理多线程的方法,其中一些方法如下:

Predictor.every(3).second().doDid(something());
Predictor.every(5).minutes().doDid(something());
Predictor.every().hour().doDid(something());
Predictor.every().week().doDid(something());
Predictor.every().month().doDid(something());

还有更多...

关于java - 在处理程序上调用时, TextView 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50883569/

相关文章:

java - 关于try-catch的问题

android - 有什么方法可以将日志转储到 Android Studio 中,以便 Android Monitor 可以重复使用它们?

java - 如何在单独的 View 中获取 TextView 的 OnClick 事件?

java - getResourceStream 无法在 eclipse 中加载新创建的文件

java - 如何将对象的Arraylist转换为Javascript?

java - 我无法导入 gradle 项目 Eclipse。 "Finish"按钮什么都不做

android - 如何从通知状态栏打开最后一个 Activity ?

android - monodroid 从 Assets 中播放视频

java - 如何使用 "departure_time"作为参数通过距离矩阵 api 将 future 时间传递到 HTTP 请求中

java - 数学或逻辑问题