从非UI线程更新UI方法中的状态

时间:2018-10-09 20:35:14

标签: java android

我有一个Activity,其中包含一个TextView,用于显示该应用程序的当前状态。除了MainActivity外,还有另一个类用于检查更新,然后在适当时更新应用程序。

这是代码的重要部分。

public class MainActivity extends AppCompatActivity {

    private TextView status;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        status  = findViewById(R.id.status);

        new Update().check();
    }

    public void setStatus(String status) {
        this.status.setText(status);
    }
}

如何从TextView类中更新状态Update

    public class Update extends Activity {
        public void check(final Context c) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    TextView status = findViewById(R.id.status);
                    status.setText("Checking for updates...");
                }
            });

            // final TextView status = getApplicationContext().findViewById(R.id.status);
            //  status.setText("Checking for updates");

            // Check for updates...

        }

        public class UpdateApp extends AsyncTask<String,Void,Void> {
            private Context context;
            public void setContext(Context contextf){
                context = contextf;
            }

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

            // Update the app

            }
        }
    }

尝试运行getApplicationContext().findViewById(R.id.status)会使应用程序崩溃。当我将其放入try块中时,它会仍然崩溃,导致应用崩溃-当我catch Throwable对象时怎么办? ...那没道理!!!

使用runOnUiThread应用程序运行,但状态未更新。

3 个答案:

答案 0 :(得分:1)

UpdateApp AsynTask放入新文件中。

public class MainActivity extends AppCompatActivity {

    private TextView status;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        status  = findViewById(R.id.status);

        new UpdateApp(status).execute();
    }
}

UpdateApp.java

public class UpdateApp extends AsyncTask<String,Void,Void> {
    private TextView status;
    public UpdateApp(TextView status){
        this.status = status;
    }
    @Override
    protected void onPostExecute(String result) {
        status.setText("Update complete");
    }

    @Override
    protected void onPreExecute() {
         status.setText("Checking for updates...");
    }
    @Override
    protected Void doInBackground(String... arg0) {

        // Update the app

    }
}

答案 1 :(得分:0)

您只是不需要其他类来使其工作,只需在MainActivity中复制您的UpdateApp类即可访问您的status视图。

如果您希望将UpdateApp类放在另一个文件中(我建议巫婆,将类职责分开),则需要回调:对您的活动的引用以更新status AsyncTask类的视图。您可以使用Interfaces来实现。看这个例子

MainActivity.java

public class MainActivity extends AppCompatActivity implements CallbackInterface {

    private TextView status;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        status  = findViewById(R.id.status);
        new LoaderClass(this).execute();
    }

    @Override
    public void setStatusText(String text) {
        status.setText(text);
    }
}

CallbackInterface.java

public interface CallbackInterface {
    void setStatusText(String text);
}

LoaderClass.java

public class LoaderClass extends AsyncTask<String, Void, Void> {
    private CallbackInterface callbackInterface;

    public LoaderClass(CallbackInterface callback) {
        callbackInterface = callback;
    }


    @Override
    protected Void doInBackground(String... arg0) {
        callbackInterface.setStatusText("Loaded text");
        return null;
    }
}

答案 2 :(得分:0)

如果您处于任何活动中,都可以使用runonUIthread(),例如-

runOnUiThread(new Runnable() {
        @Override
        public void run () {

          // do your magic here

        }
    });