[英]Trouble setting edittext from asyncTask
我在使用异步任务的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)
}
}
编辑查看堆栈跟踪,我看到此行出现在无法设置文本的电话上。 它不会出现在可以使用setText()的手机上。
`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)`
您可以在调用它时尝试将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);
}
确保您始终在主线程上调用AsyncTask.execute。 看到这个线程 ,其他人因此陷入困境。
在onPostExecute中 ,应该使用runOnUIThread来更新UI。
后台任务运行完成后,将执行onPostExecute 。
在某些设备上,完成后台任务后,UI线程可能尚未就绪。 也许主线程被锁定了...
编辑
另外,也要看看是否onCancelled被调用,而不是onPostExecute并记录错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.