下面是我使用内部类Fragment的代码。我也使用AsyncTask来执行一些后台操作。它在执行时抛出致命异常。
public class LocationFragment extends Fragment {
// Progress Dialog
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
//gps class
GPSTracker gps;
double latitude,longitude;
public TextView current_location;
private static final String BC_URL = "http://manfredinfotech.com/projects/workshop/get_location.php";
//JSON element ids from repsonse of php script:
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
public LocationFragment(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// create class object
gps = new GPSTracker(getActivity());
// check if GPS enabled
View rootView = inflater.inflate(R.layout.fragment_location, container, false);
current_location = (TextView) rootView.findViewById(R.id.current_location);
if (gps.canGetLocation()) {
latitude = gps.getLatitude();
longitude = gps.getLongitude();
// \n is for new line
Toast.makeText(getActivity(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
new GetLocation().execute();
}
return rootView;
}
class GetLocation extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute(){
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Processing...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... args){
int success;
try{
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("lat",String.valueOf(latitude)));
params.add(new BasicNameValuePair("lon", String.valueOf(longitude)));
JSONObject json = jsonParser.makeHttpRequest(BC_URL, "POST", params);
System.out.println("JSON" + json);
// check your log for json response
Log.d("Here", json.toString());
success = json.getInt(TAG_SUCCESS);
if(success == 1){
if(pDialog.isShowing())pDialog.dismiss();
System.out.println(json.getString(TAG_MESSAGE));
current_location.setText(json.getString(TAG_MESSAGE));
//return json.getString(TAG_MESSAGE);
} else {
if(pDialog.isShowing())pDialog.dismiss();
current_location.setText("Not location found");
System.out.println("Failed!");
//return json.getString(TAG_MESSAGE);
}
}
catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
}
现在这一行current_location.setText(json.getString(TAG_MESSAGE));
抛出错误。下面是我得到的例外的Stacktrace。
> 08-20 12:30:44.242 27109-27190/com.mipl.trupco E/AndroidRuntime﹕
> FATAL EXCEPTION: AsyncTask #1
> Process: com.mipl.trupco, PID: 27109
> java.lang.RuntimeException: An error occured while executing doInBackground()
> at android.os.AsyncTask$3.done(AsyncTask.java:304)
> at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
> at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
> at java.util.concurrent.FutureTask.run(FutureTask.java:242)
> at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
> at java.lang.Thread.run(Thread.java:818)
> Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
> original thread that created a view hierarchy can touch its views.
> at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
> at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:874)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.support.v4.widget.DrawerLayout.requestLayout(DrawerLayout.java:749)
> at android.view.View.requestLayout(View.java:17476)
> at android.view.View.requestLayout(View.java:17476)
> at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
> at android.view.View.requestLayout(View.java:17476)
> at android.widget.TextView.checkForRelayout(TextView.java:6871)
> at android.widget.TextView.setText(TextView.java:4057)
> at android.widget.TextView.setText(TextView.java:3915)
> at android.widget.TextView.setText(TextView.java:3890)
> at com.mipl.trupco.LocationFragment$GetLocation.doInBackground(LocationFragment.java:99)
> at com.mipl.trupco.LocationFragment$GetLocation.doInBackground(LocationFragment.java:65)
> at android.os.AsyncTask$2.call(AsyncTask.java:292)
> at java.util.concurrent.FutureTask.run(FutureTask.java:237)
> at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
> at
请帮忙
答案 0 :(得分:0)
您必须将更新ui的后台任务部分移动到主线程。有一段简单的代码:
runOnUiThread(new Runnable() {
@Override
public void run() {
//Update your UI
}
});
或者您可以在Asynctask的onPostExecute
中编写代码。
答案 1 :(得分:0)
您正在操作布局,即后台线程(doInBackground)中的current_location textview。这是不允许的,错误说明了这一点。对于操作视图元素,您应该使用onPreExecute或onPostExecute方法。
答案 2 :(得分:0)
错误在doInBackground()
时success == 1
,因为您尝试从线程编辑文本视图current_location
。
如此简单的解决方案是覆盖onPostExecute()
类中的GetLocation
方法,返回您想要的文本,并在那里设置它。在doInBackground()
if(success == 1){
if(pDialog.isShowing())pDialog.dismiss();
System.out.println(json.getString(TAG_MESSAGE));
return json.getString(TAG_MESSAGE);
} else {
if(pDialog.isShowing())pDialog.dismiss();
System.out.println("Failed!");
return "Not location found";
}
并将此新方法添加到doInBackground()
@Override
protected void onPostExecute(String result) {
if(result != null)
current_location.setText(result);
}