java - Android:异步任务:doInBackground 在 Action 回调之前返回

标签 java android android-asynctask

我正在为我的 Android 应用程序使用 MQTT。我在扩展 AsyncTask 的类中实现了 MQTT 连接。这是我的代码:

public class MainActivity extends AppCompatActivity {
    String TAG = "MQTT";
    private Context context;
    String status;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
         context = getApplicationContext();
        MQTT mqtt = new MQTT();
        mqtt.execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    public class MQTT extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            String clientId = generateClientId();
            MqttAndroidClient client =
                    new MqttAndroidClient(context, "tcp://broker.hivemq.com:1883",
                            clientId);

            try {
                IMqttToken token = client.connect();
                token.setActionCallback(new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        // We are connected
                        Log.d(TAG, "onSuccess");
                        status = "True";
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        // Something went wrong e.g. connection timeout or firewall problems
                        Log.d(TAG, "onFailure");
                        status = "False";


                    }
                });
            } catch (MqttException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "value of status " + status);
            return status;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Log.d(TAG, s);


        }
    }
}

我在这里面临的问题是 doInBackground() 在调用 onSuccess 之前返回。因此,此函数将状态返回为 null。我尝试在onPostExecute()中获取返回值的Log,它显示为null。而我在 doInBackGround 中的 onSuccess 函数中分配状态值。有没有一种方法可以确保 doInBackground 仅在 onSuccess 完成后返回。

最佳答案

快速解决方案是阻塞直到异步任务完成,例如。 G。通过使用 Semaphore:

protected String doInBackground(String... params) {
    String clientId = generateClientId();
    MqttAndroidClient client = // ....                 
    Semaphore s = new Semaphore(0);
    try {
       IMqttToken token = client.connect();
       token.setActionCallback(new IMqttActionListener() {
           @Override
           public void onSuccess() {
               // ...
               status = "True";
               s.release();
           }

           @Override
           public void onFailure() {
               // ...
               status = "False";
               s.release();
           }
       });
    } catch (MqttException e) {
         e.printStackTrace();
         s.release();
    }
    s.acquire();   // blocks until `s.release()` is invoked in callback
    return status;
}

关于java - Android:异步任务:doInBackground 在 Action 回调之前返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35243002/

相关文章:

未调用 Android BLE onCharacteristicChanged

android - 无法访问androidx.lifecycle.LifecycleOwner,Android中error是什么意思?

java - Play Framework - ErrorHandler 未被调用

java - 以编程方式更改排序列后,光标键在带有 setCellSelectionEnabled 的 TableView 中不起作用

java - customAdapter 中的运行时错误

android - 使用 ConstraintLayout 作为 DialogFragment 的根布局时的奇怪行为

java - Java排序列表,然后使用Stream API从列表中获取子列表

java - Android TCP 客户端。服务器仅在进程停止后接收消息

java - AsyncTask、Handler、Thread……选哪个

java - 如何报告不同类(class)的进度