在处理程序上调用时为空文本视图
Posted
技术标签:
【中文标题】在处理程序上调用时为空文本视图【英文标题】:Null textview when it's call on a handler 【发布时间】:2018-11-25 18:30:10 【问题描述】:我正在尝试在Handler
调用的Textview
上执行setText()
(已经在onCreate()
中实例化)并使用ruiOnUiTread()
,但我在@987654328 上有一个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);
runnable 由一个由 Volley 的 http 请求回调调用的函数启动
公共类 StarterKillerPidroid
void startApp()
//Sending a request
PostmanPidroid.getInstance().login();
public void ackLogin(Boolean isValid)
if (isValid)
ActivityMain.getInstance().doAfterLogin();
else
PostmanPidroid.getInstance().login();
邮递员类:
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);
;
【问题讨论】:
可能最好显示相关代码。 没有代码我们无法帮助您。阅读How to create a Minimal, Complete, and Verifiable example,可能在做最小的问题时,你会修复错误 我相信这个问题可能是因为你使用了不同的线程并且它在你的 onCreate 有机会初始化你的 textView 之前被执行 在调用 setText 之前尝试实例化你的 textview 问题解决了,是实例的问题 【参考方案1】:基本上,这种问题是由实例引起的。您的 textview 实例可能未初始化。直接使用处理程序更新 UI 线程的另一件事不是一个好主意。您应该使用FunctionalInterface
来执行此操作,而不是直接使用处理程序更新 Ui。
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);
并以这种方式使用它来更新 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());
还有更多...
【讨论】:
【参考方案2】:试试这个方法:
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);
;
【讨论】:
以上是关于在处理程序上调用时为空文本视图的主要内容,如果未能解决你的问题,请参考以下文章
C++:在 OBJ、OBJ&、const OBJ& 上调用时实现不同的方法
IOS 8 iPad 应用程序在调用 UIActivityViewController 时崩溃