我在使用异步任务的onPostExecute()方法设置编辑文本框的值时遇到了一些麻烦。
后台任务采用位图输入并使用Microsoft Vision API执行OCR并返回OCR结果的值。
它适用于大多数设备,但无法在运行Android 5.0的Galaxy Note 3上运行。
可以检索并烘烤后台任务的结果,没有任何错误。
异步任务
private class OCRImg extends AsyncTask<Bitmap, String, String> {
EditText gluET;
@Override
protected void onPreExecute() {
super.onPreExecute();
gluET = (EditText) ((Activity) context).findViewById(R.id.glucoseETm);
}
@Override
protected String doInBackground(Bitmap... params) {
String finalResult = "";
try {
VisionServiceClient client;
client = new VisionServiceRestClient("xxxx");
Bitmap bitmap = params[0];
ByteArrayOutputStream output = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
ByteArrayInputStream inputStream = new ByteArrayInputStream(output.toByteArray());
Gson gson = new Gson();
OCR ocr = client.recognizeText(inputStream, LanguageCodes.English, true);
String result = gson.toJson(ocr);
Log.d("result", result);
if (result != null) {
OCR r = gson.fromJson(result, OCR.class);
for (Region reg : r.regions) {
for (Line line : reg.lines) {
for (Word word : line.words) {
finalResult += word.text + " ";
}
finalResult += "\n";
}
finalResult += "\n\n";
}
}
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
Log.e("Post Error", "multipart post error " + e + "(");
}
Log.v("Final OCR Result", finalResult);
return finalResult;
}
@Override
protected void onPostExecute(String result) {
try {
result = result.replaceAll("\\D+", "");
gluET.setText(result);
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
}
}
Layout.XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/glucoseFrag"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:background="?android:attr/colorBackground"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="edu.tp.SWEN.GlucoseFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/viewPager"
android:gravity="top"
android:stretchColumns="0,1">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="0,1">
<EditText
android:id="@+id/glucoseETm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:ems="10"
android:hint="Enter glucose reading (mmol/dl)"
android:inputType="numberDecimal"
android:singleLine="true" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_camera"
android:src="@drawable/ic_camera_alt_grey_700_18dp"
android:background="@color/white"/>
</TableRow>
</TableLayout>
</ScrollView>
</FrameLayout>
调用异步任务的方法
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
glucose = (EditText) view.findViewById(R.id.glucoseET);
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
new OCRImg().execute(bitmap)
}
}
修改 查看堆栈跟踪,我看到这条线出现在无法设置文本的手机上。它不会出现在可以设置文本()的手机上。
`0`6-2`3 14:09:21.339 10547-10547/com.test.app W/FileUtils: Failed to chmod(/storage/emulated/0/com.test.app/SWEN): android.system.ErrnoException: chmod failed: EPERM (Operation not permitted)`
答案 0 :(得分:1)
您可以尝试在调用时将EditText传递给AsyncTask:
YourTask yourAsyncTask = new YourTask(YourEditText);
yourAsyncTask.execute(DoInBgParams);
然后,将其分配给AsyncTask中的成员变量:
EditText mYourEditText;
public YourTask(Editext editText){
mYourEditText = editText;
}
...
@Override
protected void onPostExecute(String result) {
mYourEditText.setText(result);
}
答案 1 :(得分:0)
确保您始终在主线程上调用AsyncTask.execute。见this thread其他人因此遇到的奇怪现象。
答案 2 :(得分:-1)
在 onPostExecute 中,您应该使用 runOnUIThread 来更新用户界面。
后台任务运行完成后,将执行onPostExecute 。
在某些设备上,当后台任务完成时,UI线程可能尚未就绪。也许主线被锁定了......
修改
同时查看是否调用 onCancelled 而不是 onPostExecute 并记录错误。