Android java 可运行的 runTimeException

Android java runnable runTimeException

我在尝试使用 setTimeout() 的等效项时遇到了一些问题,即 Android Java 中的 Runnable Thread。所以基本上我有一个名为 pathGeometries 的 Array,它存储从 API:

返回的数据
 public void getDirection(Event eventModel, final Context context) {
    String eventX = eventModel.getEventX();
    String eventY = eventModel.getEventY();

    final ArrayList<Geometry> pathGeometries = new ArrayList<Geometry>();
    try {
        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(
                "http://www.onemap.sg/API/services.svc/route/solve?token=qo/s2TnSUmfLz+32CvLC4RMVkzEFYjxqyti1KhByvEacEdMWBpCuSSQ+IFRT84QjGPBCuz/cBom8PfSm3GjEsGc8PkdEEOEr&routeStops=29741.9,40039.6;"
                        + eventX + "," + eventY + "&routemode=CYCLE");
        HttpResponse response = client.execute(request);
        HttpEntity entity = response.getEntity();
        //Code to extract and store to pathGeometries 
        } catch (JSONException e) {
            e.printStackTrace();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    for (int iii = 0; iii < pathGeometries.size(); iii++) {
        final int counter = iii;
         final Handler h = new Handler();
            h.postDelayed(new Runnable()
            {
                private long time = 0;

                public void run()
                {
                    time += 1000;
                    Log.d("TimerExample", "Going for... " + time);
                    h.postDelayed(this, 1000);
                    moveNext(pathGeometries.get(counter).getX(),
                            pathGeometries.get(counter).getY(), 0, context);
                }
            }, 1000);     
    }   
}

在 for 循环中,我循环 pathGeometries 中的每个点,通过调用 moveNext()postDelayed 将点设置为地图的中心 1 毫秒,然后移动到下一条记录.

public static void moveNext(double coordx, double coordy, int k, Context context){
    Point p = new Point(coordx, coordy);
    EventMain.mMapView.zoomToResolution(p, 1);}

但是,我收到这样的错误消息:

01-17 16:30:41.547: E/AndroidRuntime(32490): FATAL EXCEPTION: AsyncTask #5
01-17 16:30:41.547: E/AndroidRuntime(32490): java.lang.RuntimeException: An error occured while executing doInBackground()
01-17 16:30:41.547: E/AndroidRuntime(32490):    at android.os.AsyncTask.done(AsyncTask.java:278)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:208)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.lang.Thread.run(Thread.java:856)
01-17 16:30:41.547: E/AndroidRuntime(32490): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
01-17 16:30:41.547: E/AndroidRuntime(32490):    at android.os.Handler.<init>(Handler.java:121)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at android.app.Activity.<init>(Activity.java:735)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at nyp.edu.eneighbourhood.directionRunnable.<init>(directionRunnable.java:15)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at Controller.EventController.getDirection(EventController.java:301)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at AsyncTask.GetEventDirectionAsyncTask.doInBackground(GetEventDirectionAsyncTask.java:34)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at AsyncTask.GetEventDirectionAsyncTask.doInBackground(GetEventDirectionAsyncTask.java:1)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at android.os.AsyncTask.call(AsyncTask.java:264)
01-17 16:30:41.547: E/AndroidRuntime(32490):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-17 16:30:41.547: E/AndroidRuntime(32490):    ... 5 more

有什么解决办法吗?因为我不确定我是否做对了。提前致谢。

编辑 在我的 UI Thread:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    final Handler handler = new Handler();
}

btnGetDirection.setOnClickListener(new OnClickListener() {
        String direction = "";
        int counter = 1;
        ArrayList<String> directionList = new ArrayList<String>();

        public void onClick(View v) {
                            eventModel.setEventX(String.valueOf(eventModel.getEventX()));
            eventModel.setEventY(String.valueOf(eventModel.getEventY()));
            new GetEventDirectionAsyncTask(
                    new GetEventDirectionAsyncTask.OnRoutineFinished() {
                        public void onFinish() {
                            // Hide the callout and plot user location
                            // marker
                                                // close the progress dialog
                            progressDialog.dismiss();
                        }
                    }, handler).execute(eventModel);
        }
    });

在 GetEventDirectionAsyncTask 中 class:

public class GetEventDirectionAsyncTask extends AsyncTask<Event, Integer, Double> {
EventController eventCtrl = new EventController();
public static ArrayList<String> directionList = new ArrayList<String>();
Context context;
Handler handler;

public interface OnRoutineFinished { // interface
    void onFinish();
}

private OnRoutineFinished mCallbacks;

public GetEventDirectionAsyncTask(OnRoutineFinished callback, Handler handler) { // constructor with
                                                    // interface
    mCallbacks = callback;
    this.handler = handler;
}

public GetEventDirectionAsyncTask() {
} // empty constructor to maintain compatibility


@Override
protected Double doInBackground(Event... params) {
    if (params.length == 1) {
        eventCtrl.getDirection(params[0], context);
        directionList = eventCtrl.getDirectionPath(params[0], context);
    }
    return null;
}

protected void onPostExecute(Double result) {
    if (mCallbacks != null)
        mCallbacks.onFinish(); // call interface on finish
}

protected void onProgressUpdate(Integer... progress) {
}

}

在我的控制器中 class getDirection 方法:

for (int iii = 0; iii < pathGeometries.size(); iii++) {
        final int counter = iii;
         final Handler h = new Handler();
            h.postDelayed(new Runnable()
            {
                private long time = 0;

                public void run()
                {
                    time += 1000;
                    Log.d("TimerExample", "Going for... " + time);
                    h.postDelayed(this, 1000);
                    moveNext(pathGeometries.get(counter).getX(),
                            pathGeometries.get(counter).getY(), 0, context);
                }
            }, 1000); 

RuntimeException: Can't create handler inside thread that has not...

因为您试图从 doInBackground Thread 而不是 UI Thread

调用 moveNext

修复以下错误:

第一个选项:在Activity中的class级别声明Handler h并在onCreate方法或任何方法中初始化它运行 在 UI 线程上的方法,如 onPreExecute()

`Handler handle;
public GetEventDirectionAsyncTask(OnRoutineFinished callback,
                                  Handler handle){
  this.handle=handle;
  ...
 }`

从 Activity 传递 hanlder 作为:

final Hanlder hanlder=new Hanlder();
btnGetDirection.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {

           GetEventDirectionAsyncTask obj= new GetEventDirectionAsyncTask(
                    new GetEventDirectionAsyncTask.OnRoutineFinished() {
                        public void onFinish() {
                           ...
                        }
                    },hanlder).execute(eventModel);
        }
    });

现在使用 handledoInBackground

调用 postDelayed

第二个选项: 使用 runOnUiThread 从 UI 线程创建和调用处理程序:

  YourActivity.this.runOnUiThread(new Runnable() {
     @Override
     public void run() {
        create and call postDelayed method from Handler here
      }
  });