Java 为什么AsyncTask doInBackground不';它不会跑,但第二次会跑

Java 为什么AsyncTask doInBackground不';它不会跑,但第二次会跑,java,android,android-asynctask,Java,Android,Android Asynctask,所以我是新来的,我需要调用从单独文件运行AsyncTask的函数 MainActivity.java代码 public class MainActivity extends AppCompatActivity { String res; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.

所以我是新来的,我需要调用从单独文件运行AsyncTask的函数

MainActivity.java代码

public class MainActivity extends AppCompatActivity {
String res;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Asynctasktest newAsy = new Asynctasktest();



    res = newAsy.ValidateUser();

    Toast.makeText(getBaseContext(), "'"+res+"'", Toast.LENGTH_LONG).show();
}

}
public class Asynctasktest extends MainActivity {

String Res;

private class GetFWork extends AsyncTask<Void,Void,String> {

    @Override
    protected void onPreExecute() {
        Res = "onPreExecute";
    }

    @Override
    protected String doInBackground(Void... param) {

        return "am i here";
    }

    @Override
    protected void onPostExecute(String Result) {
        super.onPostExecute(Result);
        Res = Result;
    }
}

public String ValidateUser(){

    final GetFWork Fl = new GetFWork();

    Fl.execute();

    return Res;
}


}
和AsyncTaskTest.java代码

public class MainActivity extends AppCompatActivity {
String res;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Asynctasktest newAsy = new Asynctasktest();



    res = newAsy.ValidateUser();

    Toast.makeText(getBaseContext(), "'"+res+"'", Toast.LENGTH_LONG).show();
}

}
public class Asynctasktest extends MainActivity {

String Res;

private class GetFWork extends AsyncTask<Void,Void,String> {

    @Override
    protected void onPreExecute() {
        Res = "onPreExecute";
    }

    @Override
    protected String doInBackground(Void... param) {

        return "am i here";
    }

    @Override
    protected void onPostExecute(String Result) {
        super.onPostExecute(Result);
        Res = Result;
    }
}

public String ValidateUser(){

    final GetFWork Fl = new GetFWork();

    Fl.execute();

    return Res;
}


}
公共类Asynctasktest扩展了MainActivity{
字符串Res;
私有类GetFWork扩展了AsyncTask{
@凌驾
受保护的void onPreExecute(){
Res=“onPreExecute”;
}
@凌驾
受保护字符串doInBackground(无效…参数){
返回“我在这里”;
}
@凌驾
受保护的void onPostExecute(字符串结果){
super.onPostExecute(结果);
Res=结果;
}
}
公共字符串ValidateUser(){
最终GetFWork Fl=新GetFWork();
Fl.execute();
返回Res;
}
}

所以我需要得到文本“我在这里吗”,但我得到了“onPreExecute”,这表明在第一次调用时,它不会在后台执行任务。

这就是AsyncTask的工作方式

res = newAsy.ValidateUser();
Toast.makeText(getBaseContext(), "'"+res+"'", Toast.LENGTH_LONG).show();

都是同时执行的,因此,由于AsyncTask是异步的,所以res的值仍然是“onPreExecute”。

Wukash提出了一个很好的观点。我只是想详细说明一下。ValidateUser()返回
Res
时,无法保证
AsyncTask
已完成运行,因为它是异步的,并从主线程运行。因此,在您的例子中,它返回
null
,因为
Res
从未更新过

如果您需要返回值
result
来更新UI或其他内容,请将处理程序函数引用作为回调发送,并使其能够执行此操作


如果你需要进一步的解释,请告诉我。我记得在我第一次实现
AysncTask
时遇到过类似的问题。

尝试用这种方法调用super

@Override
protected void onPreExecute() {
    super.onPreExecute();
    Res = "onPreExecute";
}
还要记住,不能两次调用同一AsyncTask对象,否则会出现以下错误:

Cannot execute task: the task has already been executed (a task can be executed only once)

因此,在ValidateUser()方法中创建新GetFWork()的方法很好。

这是一种非常原始的跟踪应用程序中发生的事情的方法。使用
Log
或简单地使用断点进行调试。第一次调用应该命中doInBackground(..)
。添加
android.os.Debug.waitForDebugger();`在
doInBackground(..)
的开头,放置一个断点,看看它是否命中函数。AsyncTask的全部目的是它是“异步的”。您不能执行()它,而期望在下一行代码中包含结果。有大量资源可用于设置回调。我用了那个例子,让它在我的测试中发挥作用。因此,我需要使用Asynctask对php进行不同的调用,我必须传递一些参数,然后像在OnPreExecute中一样,我构建链接,在doInBackground上调用httpurlconnection并等待答案。还是有更好的方法?@IvarsAkmentins我觉得你在那里很不错。也许也可以把链接建筑移到doInBackground,因为你真的不需要它同步发生。一个好的OOP方法可以是实例化
Asynctasktest
对象,初始化链接构建所需的一组参数,并将所有内容卸载到doInBackground。这将导致一个非常坚实的设计。