6

AIButton在我的应用程序中使用,我有一个AsyncTask在单击 AIButton 并接收一些命令后执行的操作,并且 AsyncTask 有时需要很长时间才能执行。

这是我的代码:

final AIConfiguration config = new AIConfiguration("xxx",
                AIConfiguration.SupportedLanguages.English,
                AIConfiguration.RecognitionEngine.System);

listenButton = (AIButton) findViewById(R.id.micButton);

config.setRecognizerStartSound(getResources().openRawResourceFd(R.raw.test_start));
config.setRecognizerStopSound(getResources().openRawResourceFd(R.raw.test_stop));
config.setRecognizerCancelSound(getResources().openRawResourceFd(R.raw.test_cancel));

listenButton.initialize(config);
listenButton.setResultsListener(this);

这是AsnycTask

class translate extends AsyncTask<String, Void, String> {

    String translatedText = "";

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        loading.setMessage("Loading");
        loading.show();
    }

    @Override
    protected String doInBackground(String... params) {

        String text = params[0];
        String toBeConvertedIn = params[1];

        Log.d("TEXT", text);
        Log.d("TBCI", toBeConvertedIn);

        try {
            String encodedText = URLEncoder.encode(text, "UTF-8");
            HttpHandler httpHandler = new HttpHandler();
            String url = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=xxxxxxx&text=" + encodedText + "&lang=" + toBeConvertedIn;
            String jsonStr = httpHandler.makeServiceCall(url);

            if (jsonStr != null) {
                Log.e(TAG, "Response from url: " + jsonStr);
                try {
                    JSONObject jsonObj = new JSONObject(jsonStr);
                    Log.d("jsonObj", String.valueOf(jsonObj));

                    JSONArray translatedTextObj = jsonObj.getJSONArray("text");

                    for (int i=0; i<translatedTextObj.length(); i++) {
                        translatedText = translatedTextObj.getString(i);
                        Log.d("translatedText", translatedText);
                    }

                } catch (JSONException e) {
                    Log.d(TAG, e.getMessage());
                }
            } else {
                Log.e(TAG, "Couldn't get json from server.");
            }

        } catch (UnsupportedEncodingException e) {
            Log.d(TAG, e.getMessage());
        }

        return translatedText;
    }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            hTV.setText(s);
            if (loading.isShowing()) {
                loading.dismiss();
            }
        }
    }

我在上面以这样AsyncTaskonResult()方法调用:

public void onResult(final AIResponse response) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "onResult");

            Log.i(TAG, "Received success response");

            // this is example how to get different parts of result object
            final Status status = response.getStatus();
            Log.i(TAG, "Status code: " + status.getCode());
            Log.i(TAG, "Status type: " + status.getErrorType());

            final Result result = response.getResult();
            Log.i(TAG, "Resolved query: " + result.getResolvedQuery());

            Log.i(TAG, "Action: " + result.getAction());
            final String speech = result.getFulfillment().getSpeech();

            final Metadata metadata = result.getMetadata();
            if (metadata != null) {
                Log.i(TAG, "Intent id: " + metadata.getIntentId());
                Log.i(TAG, "Intent name: " + metadata.getIntentName());
            }

            final HashMap<String, JsonElement> params = result.getParameters();
            if (params != null && !params.isEmpty()) {
                Log.i(TAG, "Parameters: ");
                for (final Map.Entry<String, JsonElement> entry : params.entrySet()) {

                    switch (response.getResult().getMetadata().getIntentName()) {
                        case "Translate":
                            if (entry.getValue() != null) {
                                if (entry.getKey().equals("translate")) {

                                    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
                                    LayoutInflater inflater = MainActivity.this.getLayoutInflater();
                                    final View dialogView = inflater.inflate(R.layout.translate_alertdialog, null);
                                    dialogBuilder.setView(dialogView);

                                    final EditText textToTranslate = (EditText) dialogView.findViewById(R.id.text_to_translate);
                                    final AutoCompleteTextView chooseLanguage = (AutoCompleteTextView) dialogView.findViewById(R.id.choose_language);
                                    ArrayAdapter adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_item, languages);
                                    chooseLanguage.setAdapter(adapter);

                                    dialogBuilder.setTitle("What should I translate?");
                                    dialogBuilder.setPositiveButton("Translate", new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int whichButton) {
                                            if (!textToTranslate.getText().toString().isEmpty()) {
                                                if (!chooseLanguage.getText().toString().isEmpty()) {

                                                    switch (chooseLanguage.getText().toString().toLowerCase()) {
                                                        case "french":
                                                            new translate().execute(textToTranslate.getText().toString(), "az");
                                                            break;
                                                    }
                                                }
                                            }
                                        }
                                    });
                                    dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int whichButton) {
                                            //pass

                                        }
                                    });
                                    AlertDialog b = dialogBuilder.create();
                                    b.show();
                                } else {
                                    Log.d("null", "No translate parameter");
                                }
                            } else {
                                Log.d("null", "No translate entry value");
                            }
                            break;
                    }
                }
            }
        }

    });

}

所以,我想要的是在单击 AIButton 时停止所有正在运行的 AsyncTask,以便停止以前的任务以执行新任务。这个怎么做?

这里的问题是你不能做这样的事情:listenButton.onClickListener()在这里。

4

4 回答 4

2

使用布尔取消 (boolean mayInterruptIfRunning)

使 asyncTask 成为类变量。

AsyncTask translate_ = new translate();

然后就这样调用它。

translate_.execute(textToTranslate.getText().toString(), "az");

在 onclick 按钮内取消 asyncTask。

translate_.cancel(true);

然后在您的循环中检查任务是否已被取消并设置中断。

for (int i=0; i<translatedTextObj.length(); i++) {
    translatedText = translatedTextObj.getString(i);
    Log.d("translatedText", translatedText);
    if(isCancelled())
        break;
}

这些问题还为如何选择执行此操作提供了更多选择:

Android - 强制取消 AsyncTask

如何在android中停止异步任务线程?

在后台管理任务也是明智的。也许取消活动 onpause 中的任务。

public void listenButtonOnClick(final View view) {
    // aiService.startListening();
    // add more details in here

    if (aiService != null) {
        switch (currentState) {
            case normal:
                aiService.startListening();
                break;
            case busy:
                aiService.cancel();
                translate_.cancel(true);
                break;
            default:
                aiService.stopListening();
                translate_.cancel(true);
                break;
}

或者在aiservice取消或停止时取消任务。

@Override
public void onListeningStarted() {}

@Override
public void onListeningCanceled() {
    translate_.cancel(true);
}

@Override
public void onListeningFinished() {
    translate_.cancel(true);
}

还有其他方法可以管理它,探索您的选择。好好看看这个和上面链接的 SO 问题。

如果您查看文档

apiai-android-client/ailib/src/main/java/ai/api/ui/AIButton.java

@Override
protected void onClick(final View v) {
    super.onClick(v);

    if (aiService != null) {
        switch (currentState) {
            case normal:
                aiService.startListening();
                break;
            case busy:
                aiService.cancel();
                break;
            default:
                aiService.stopListening();
                break;
        }
    }

}

我们的讨论中可以清楚地看出,您正在为如何实现这一点而苦苦挣扎。

请学习这个apiai-android-client/ Android SDK for api.ai/ 教程

回到基础。暂时忘掉它ai.api并学习基础知识。浏览,阅读文档Input Events阅读问题并应用编程原则。例如:
Android 按钮 onclick 覆盖

除此之外,我无法再为您提供任何帮助。

于 2017-09-10T17:05:02.750 回答
1

取消 AsyncTask 时,您必须做以下一件事。在您的按钮单击方法上。

public void AIButtonClick(View view){
  asyncTask.cancel(false);
}

并检查 doInBackground 如果它被取消然后从它返回。

    @Override
    protected String doInBackground(String... params) {     
     if(asyncTask.isCanceled()) return;
   }

同样在您的 onPause 方法中,您已经取消它很好。

@Override
public void onPause() {
    super.onPause();
     if(asyncTask!=null){
      asyncTask.cancel(false);

   }
}
于 2017-09-14T06:37:43.207 回答
0

如果要取消 AsyncTask 类 translate.cancel()

如果要取消服务器请求我建议使用 OKHTTP 具有取消请求功能

于 2017-09-16T21:28:01.183 回答
0

尝试为您的 AIButton 设置 resultListener 并实现 onCancelled() 方法从那里取消您的 AsyncTasks。

要将 AsyncTask 标记为需要停止,您应该调用

asyncTask.cancel(false);

在您的 AsyncTask 中,您必须通过调用定期检查它是否被取消isCancelled()。如果此方法返回 true,您应该停止执行。

于 2017-09-10T16:55:45.287 回答