簡體   English   中英

Android Java Runnable RunTimeException

[英]Android java runnable runTimeException

嘗試使用setTimeout()的等效項setTimeout()在Android Java中為Runnable Thread setTimeout()時遇到了一些問題。 所以基本上我有一個名為pathGeometries的Array ,該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毫秒,然后再移至下postDelayed記錄。

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$3.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$1.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$2.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類中:

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) {
}

}

在我的Controller類的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:無法在沒有...的線程內創建處理程序

因為您正在嘗試從doInBackground線程而不是UI線程調用moveNext

要修復以下錯誤:

第一種選擇:在Activity的類級別聲明Handler h並在onCreate方法或在UI線程上運行的任何方法onPreExecute()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);
        }
    });

現在,使用handle來調用postDelayeddoInBackground

第二種選擇:使用runOnUiThread從UI Thread創建並調用處理程序:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM