Android java runnable runTimeException

Android java runnable runTimeException

本文关键字:runTimeException runnable java Android      更新时间:2023-09-26

我在尝试使用Android Java中Runnable Thread的等效setTimeout()时遇到了一些问题。所以基本上我有一个名为pathGeometrys的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$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) {
}

}

在我的控制器类 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); 

运行时异常:无法在线程中创建没有...

因为您尝试从 doInBackground Thread 而不是 UI Thread 调用moveNext

要修复以下错误:

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

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

将 Hanlder 从 Activity 传递为:

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
      }
  });
相关文章:
  • 没有找到相关文章