所以我正在尝试创建一个通过 ssh 连接同步文件的应用程序。 ssh 连接作为 AsyncTask 启动,我希望它在 onPostExecute 方法内设置 UI 元素的文本,但似乎无法在其中声明或使用必要的变量。
public class MainActivity extends AppCompatActivity {
public TextView infoView = (TextView) findViewById(R.id.infoView);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new sshConnectTask().execute();
}
static class sshConnectTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void...params){
/*STUFF*/
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
infoView.setText("ASD");
}
}
}
基本上我想在 onPostExecute 方法中调用 infoView.setText() 。
更新 Discord 上有人帮我解决了这个问题:
setContentView 必须在 findViewByID 之前调用;否则 findViewById 只是返回 mull
infoView 变量可以像这样传递给 SSHConnectTask
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView infoView = (TextView) findViewById(R.id.infoView); new SSHConnectTask(infoView).execute(); }
那么 SSHConnectTask 必须进行调整
static class SSHConnectTask extends AsyncTask<Void, Void, Void> { private TextView display; public SSHConnectTask(TextView display){ this.display = display; }
之后,可以在 onPostExecute 中设置 infoViews 文本
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
display.setText("TEST");
最佳答案
在调用异步代码时使用 WeakReference 是一种黑客行为,您应该做的是使用去年(2017 年)发布的 Android 架构组件,它可以让您简化此类事情。
因此,您有一个观察 View 模型中的数据的 Activity :
public class MainActivity extends AppCompatActivity {
private TextView infoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
infoView = findViewById(R.id.infoView);
MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
mainViewModel.infoText.observe(this, (text) -> {
infoView.setText(text);
});
}
}
并且您应该创建一个 ViewModel,其中在存储在 ViewModel 中的 LiveData 内处理此类连接:
public class MainViewModel extends ViewModel {
LiveData<String> infoText = new InfoTextLiveData();
public MainViewModel() {
}
}
并且您的 LiveData 应该知道如何获取数据:
public class InfoTextLiveData extends MutableLiveData<String> {
@Override
protected void onActive() {
new SshConnectTask().execute(); // optionally, you could `cancel()` the asyncTask in `onInactive()`
}
class SshConnectTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void...params){
/*STUFF*/
postValue("ASD");
return null;
}
}
}
<小时/>
为此,您必须添加 AAC 依赖项:
allprojects {
repositories {
jcenter()
google()
}
}
和
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
<小时/>
有关更多信息,请参阅指南:
关于java - 从静态 AsyncTask 方法内部访问 Android UI 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50395053/