因此,我试图创建一个通过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体系结构组件,它可以简化这种事情。

因此,您有一个活动来观察视图模型中的数据:

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"




有关更多信息,请参阅指南:

https://developer.android.com/jetpack/docs/guide

10-06 14:37