在调用处理程序时调用空文本视图

时间:2018-06-15 22:54:04

标签: java android android-activity view handler

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

问题出在哪里?

我在调试中看到activity的实例在实例化和setText()之间不一样,而我没有更改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); }

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

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

runnable由一个使用Volley

的回调调用的函数启动 公共类StarterKillerPidroid {

  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);
        }
    };

收到成功回复后,将调用此回调:

RootClass

2 个答案:

答案 0 :(得分:2)

基本上,这种问题是由于实例引起的。您的textview实例可能未初始化。直接使用处理程序更新UI线程的另一件事不是一个好主意。代替使用处理程序直接更新Ui,您应该使用FunctionalInterface进行此操作。

FunctionalInterface是处理此类情况的好方法。

  

功能接口是仅包含一个抽象方法的接口。他们只能展示一种功能。从Java 8开始,lambda表达式可用于表示功能接口的实例。 ... Runnable,ActionListener和Comparable是功能接口的一些示例。

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);
}

,并以此方式更新用户界面

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

有一个适用于Android的开放源代码库,其工作原理很像Predictor这样的符咒。您可以从one from Microsoft下载它并导入到您的项目中。您也可以为这个项目做出贡献,以挽救许多开发人员的生命。

您想看看预测变量如何做到这一点吗?

 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());

还有更多...

答案 1 :(得分:0)

尝试这种方式:

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