Android 运行其他线程不允许显示活动
我有一项活动:Android 运行其他线程不允许显示活动,android,multithreading,android-layout,android-activity,java.util.concurrent,Android,Multithreading,Android Layout,Android Activity,Java.util.concurrent,我有一项活动: public class ResultActivity extends AppCompatActivity implements ResultListener { private String code = ""; private String data = ""; @Override protected void onCreate(Bundle savedInstanceState) {
public class ResultActivity extends AppCompatActivity implements ResultListener {
private String code = "";
private String data = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
code = intent.getStringExtra("code");
data = intent.getStringExtra("data");
MyExternal.DecodeAndSend(this, code, data);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
其中,MyExternal
是其他库中的一个类
方法DecodeAndSend
如下所示:
public static boolean DecodeAndSend(ResultListener caller, String codigo, String data)
{
try {
ExecutorService pool = Executors.newFixedThreadPool(1);
HashMap<String,String> arguments = new HashMap<>();
Future<String> resultado = pool.submit(new ServerConnection(caller, url, arguments));
String status = resultado.get();
if (status.equals("OK"))
caller.OnSuccess();
else
caller.OnError(status);
pool.shutdown();
return true;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return false;
}
调用Thread.sleep(2000)
实际上是对web服务器的调用,以发送一些数据
问题是,ResultActivity
在调用返回之前不会显示其布局
此代码中缺少什么?Future.get()
是一个-执行将停止,直到结果到达
只有在计算完成后,才能使用方法get检索结果,如有必要,请阻塞,直到它准备就绪
因此,您的活动
的onCreate
方法调用该内容,然后阻塞,直到调用
(在另一个线程上运行)返回其结果。因此,onCreate
没有完成,布局也没有完成
如果您想使用该阻塞代码,但在视图布局之后,我会使用另一部分,如onStart
(设置一个标志,以便只运行一次!)。否则,您将需要使用其他一些并发技术来获得结果并使用它。这取决于您对调用的结果实际执行的操作。get()
是一个-执行将停止,直到结果到达
只有在计算完成后,才能使用方法get检索结果,如有必要,请阻塞,直到它准备就绪
因此,您的活动
的onCreate
方法调用该内容,然后阻塞,直到调用
(在另一个线程上运行)返回其结果。因此,onCreate
没有完成,布局也没有完成
如果您想使用该阻塞代码,但在视图布局之后,我会使用另一部分,如onStart
(设置一个标志,以便只运行一次!)。否则,您将需要使用其他一些并发技术来获得结果并使用它。这取决于您对调用
函数功能的结果实际执行的操作。get()
是一个阻塞调用。UI线程在等待调用返回时被阻塞,因此无法绘制布局。尝试将结果侦听器传递到ResultListener
到ServerConnection
,并使用这两个回调相应地更新UI功能。get()
是一个阻塞调用。UI线程在等待调用返回时被阻塞,因此无法绘制布局。尝试将结果侦听器传递到ResultListener
到ServerConnection
,并使用这两个回调相应地更新您的UIDecodeAndSend
从主线程调用。它调用Future.get()
,等待作业完成,因此它阻塞了主线程。您也应该从后台线程调用此方法。我认为可以将它发送到同一个线程池,因为它是在等待的第一个作业之后提交的
您不能从这个方法返回任何关于请求结果的信息,因为它是异步的
public static void DecodeAndSend(ResultListener caller, String codigo, String data)
{
ExecutorService pool = Executors.newFixedThreadPool(1);
HashMap<String,String> arguments = new HashMap<>();
Future<String> resultado = pool.submit(new ServerConnection(caller, url, arguments));
pool.submit(new Runnable() {
public void run () {
try {
String status = resultado.get();
if (status.equals("OK"))
caller.OnSuccess();
else
caller.OnError(status);
pool.shutdown();
return;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
caller.OnError(null); // No status, only an exception
});
}
publicstaticvoiddecodeandsend(ResultListener调用者、字符串codigo、字符串数据)
{
ExecutorService池=Executors.newFixedThreadPool(1);
HashMap参数=新的HashMap();
Future resultado=pool.submit(新服务器连接(调用者、url、参数));
pool.submit(新的Runnable(){
公开作废运行(){
试一试{
字符串状态=resultado.get();
如果(状态等于(“正常”))
caller.OnSuccess();
其他的
调用方。OnError(状态);
pool.shutdown();
返回;
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}捕获(执行例外){
e、 printStackTrace();
}
caller.OnError(null);//没有状态,只有异常
});
}
但是,您的ServerConnection
类已经接受了caller
参数,因此它可能只处理回调本身。根据您在回调中的操作,您可能希望将回调调用发布到主线程
顺便说一句,Java中的惯例是总是以小写字母(驼峰大小写)开头方法名。DecodeAndSend
是从主线程调用的。它调用Future.get()
等待作业完成,因此它会阻塞主线程。您也应该从后台线程调用此方法。我认为可以将其发送到同一线程池,因为它是在等待的第一个作业之后提交的
您不能从这个方法返回任何关于请求结果的信息,因为它是异步的
public static void DecodeAndSend(ResultListener caller, String codigo, String data)
{
ExecutorService pool = Executors.newFixedThreadPool(1);
HashMap<String,String> arguments = new HashMap<>();
Future<String> resultado = pool.submit(new ServerConnection(caller, url, arguments));
pool.submit(new Runnable() {
public void run () {
try {
String status = resultado.get();
if (status.equals("OK"))
caller.OnSuccess();
else
caller.OnError(status);
pool.shutdown();
return;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
caller.OnError(null); // No status, only an exception
});
}
publicstaticvoiddecodeandsend(ResultListener调用者、字符串codigo、字符串数据)
{
ExecutorService池=Executors.newFixedThreadPool(1);
HashMap参数=新的HashMap();
Future resultado=pool.submit(新服务器连接(调用者、url、参数));
pool.submit(新的Runnable(){
公开作废运行(){
试一试{
字符串状态=resultado.get();
如果(状态等于(“正常”))
caller.OnSuccess();
其他的
调用方。OnError(状态);
pool.shutdown();
返回;
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}捕获(执行例外){
e、 printStackTrace();
}
caller.OnError(null);//没有状态,只有异常
});
}