问题描述
我有一个线程读者
读取文件并更新列表A.另一个线程抽屉
读什么就有什么的变量,做一些事情,调用的OnDraw然后休眠500毫秒(在此期间,读者填充A)。
我也有一个启动,如果我preSS菜单按钮preference活动。
现在的问题是,如果我preSS按钮的同时读线程还没有完成阅读他的文件,我有恩在logcat中的错误。(见下文)
我已经看到了,问题是,正在运行时,它让我看到preference菜单,其实读线程,如果我等到读者结束,我点击一个preference一切顺利好了,但如果我点击,而其运行igot错误。
我该如何处理仍在运行,当我anewactivity启动线程?如何暂停
呢? Becouse我的文件读取可以bevery长,所以我不能等那么读线程结束。
感谢
编辑:为了更precise,什么appens的是,如果我preSS菜单按钮时,preferenceActivity开始,我看到了正确预览(单选按钮等),但问题是当我点击屏幕上的任意一点,它给我的错误。如果我等那么读thred结束(我看到它从logcat中),然后我点击ARANDOM点,它会everithing好...
logcat的错误:
10月二号至三号:18:51.196:ERROR / ActivityManager(66):ANR在it.planningpathapp.ale(it.planningpathapp.ale /.preferences)
十月2日至3号:18:51.196:ERROR / ActivityManager(66):原因:keyDispatchingTimedOut
十月2日至3号:18:51.196:ERROR / ActivityManager(66):负载:0.7 / 0.29 / 0.29
十月2日至3号:18:51.196:ERROR / ActivityManager(66):CPU使用率从13441ms到36ms前:
十月2日至3号:18:51.196:ERROR / ActivityManager(66):ningpathapp.ale:82%= 75%的用户+ 7%核心/故障:6211次要1大
十月2日至3号:18:51.196:ERROR / ActivityManager(66):adbd:16%= 0%用户+ 15%核心/故障:36未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):system_server:11%= 8%的用户+ 3%的内核/故障:229未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):logcat的:3%= 1%的用户+ 2%的内核
十月2日至3号:18:51.196:ERROR / ActivityManager(66):m.android.phone:0%= 0%用户+ 0%,核心/故障:33未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):ronsoft.openwnn:0%= 0%用户+ 0%,核心/故障:30未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):m.android.music:0%= 0%用户+ 0%,核心/故障:52未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):id.defcontainer:0%= 0%用户+ 0%,核心/故障:14未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):com.svox.pico:0%= 0%用户+ 0%,核心/故障:15未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):ndroid.launcher:0%= 0%用户+ 0%,核心/故障:18未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):com.android.mms:0%= 0%用户+ 0%,核心/故障:22未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):m.android.email:0%= 0%用户+ 0%,核心/故障:41未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):android.protips:0%= 0%用户+ 0%,核心/故障:15未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):.quicksearchbox:0%= 0%用户+ 0%,核心/故障:34未成年人
十月2日至3号:18:51.196:ERROR / ActivityManager(66):总计:99%= 72%的用户+ 20%内核+ 1%的IRQ + 6%软中断
十月2日至3号:18:51.216:WARN /窗口管理器(66):无窗派遣指针动作1
公共类PathPlanningApp1Activity延伸活动{私有静态对象锁=新的对象();每1L调试mediante LogCat中//三重标签私有静态最后弦乐TAG_readFile =READFILE_thread;私有静态最后弦乐TAG_draw =DRAW_Thread;私有静态最后弦乐TAG_error =错误;私人最终的HashMap<整数,顶点>图=新的HashMap<整数,顶点> ();私人最终链表<顶点> originalPath =新的LinkedList<顶点> ();私人最终链表<顶点> ORIGINALE =新的LinkedList<顶点> ();私人最终的ArrayList<顶点>障碍=新的ArrayList<点>();私人最终的ArrayList<顶点> obstacles_notordered =新的ArrayList<点>();私人诠释mapWidth = 1;私人诠释mapHeight = 1;面板面板;资源资源;私人位图mBitmap;私人位图obstaclesBmp = Bitmap.createBitmap(2,2,Bitmap.Config.ARGB_8888);私人浮动变焦= 15;/ **第一次创建活动时调用。 * /@覆盖公共无效的onCreate(包savedInstanceState){ super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); RES = this.getResources(); 面板=新的面板(本); 的setContentView(板); Log.d(getLocalClassName(),上创建);}公共布尔onCreateOptionsMenu(功能菜单){ MenuInflater充气= getMenuInflater(); inflater.inflate(R.menu.menu,菜单); 返回true;}保护无效onResume(){Log.d(getLocalClassName(),关于RESUME); 的setContentView(板); super.onResume();}保护无效的onDestroy(){ Log.d(getLocalClassName(),关于消灭); super.onDestroy();}保护无效的onPause(){ Log.d(getLocalClassName(),开暂停); Log.d(getLocalClassName(),stato抽屉+ panel.drawerThread.getState()); Log.d(getLocalClassName(),stato frt位+ panel.frt.getState()); super.onPause();}@覆盖公共布尔onOptionsItemSelected(菜单项项){ 开关(item.getItemId()){ 案例R.id.ic_launcher:Toast.makeText(这一点,你pressed图标!,Toast.LENGTH_LONG).show(); 意图settingsActivity =新的意图(这一点,preferences.class); startActivity(settingsActivity); 打破; 案例R.id.text:Toast.makeText(这一点,你pressed的文字!,Toast.LENGTH_LONG).show(); 打破; 案例R.id.icontext:Toast.makeText(这一点,你pressed的图标和文字!,Toast.LENGTH_LONG).show(); 打破; } 返回true;}类面板扩展了SurfaceView实现SurfaceHolder.Callback { FileReaderThread FRT =新FileReaderThread(); DrawerThread drawerThread; 公共面板(上下文的背景下){ 超(上下文); 。getHolder()的addCallback(本); drawerThread =新DrawerThread(getHolder(),这一点); setDrawingCacheEnabled(真正的); setFocusable(真正的); } 公共无效的OnDraw(帆布油画){ canvas.drawColor(Color.BLACK); 尝试{ INT I = 0; INT高= canvas.getHeight(); INT宽度= canvas.getWidth(); 涂料粉刷=新的油漆(); paint.setColor(Color.GREEN); //Log.d(TAG_draw,obstaclesBmp =+ obstaclesBmp.getHeight()); 如果(obstaclesBmp!= NULL){ 同步(obstaclesBmp){ canvas.drawBitmap(obstaclesBmp,0,0,NULL); } } }赶上(OutOfMemoryError异常E){ Log.e(TAG_error的OnDraw !!位图过于格罗萨暗淡:+ mapWidth ++ mapHeight); } } 公共无效surfaceChanged(SurfaceHolder持有人,INT格式,诠释的宽度, INT高度){ // TODO自动生成方法存根 } 公共无效surfaceCreated(SurfaceHolder持有者){ // TODO自动生成方法存根 如果(frt.getState()== Thread.State.TERMINATED){ // FRT =新FileReaderThread(); // frt.start(); //< - 增加了修复 }其他 { Log.d(TAG_readFilestato frt位+ frt.getState()); frt.setRunning(真正的); frt.start(); } 如果(drawerThread.getState()== Thread.State.TERMINATED){ drawerThread =新DrawerThread(getHolder(),这一点); drawerThread.setRunning(真正的); drawerThread.start(); } 其他{ drawerThread.setRunning(真正的); drawerThread.start(); } } 公共无效surfaceDestroyed(SurfaceHolder持有者){ // TODO自动生成方法存根 布尔重试= TRUE; drawerThread.setRunning(假); 而(重试){ 尝试 { drawerThread.join(); 重试= FALSE; }赶上(InterruptedException异常E){ //我们会一次又一次地尝试... } } 重试= TRUE; frt.setRunning(假); 而(重试){ 尝试 { frt.join(); 重试= FALSE; }赶上(InterruptedException异常E){ //我们会一次又一次地尝试... } } }}公共类DrawerThread继承Thread { 私人SurfaceHolder _surfaceHolder; 私人面板_panel; 私人布尔_run = FALSE; 位图oldbmp = NULL; 位图newbmp = NULL; 位图obstaclesBmpTmp = NULL; INT I = 0; INT lasti = 0; INT oldW = -1,oldH = -1; 公共DrawerThread(SurfaceHolder surfaceHolder,面板面板){ _surfaceHolder = surfaceHolder; _panel =面板; } 公共无效setRunning(布尔运行){ _run =运行; } 公共SurfaceHolder getSurfaceHolder(){ 返回_surfaceHolder; } 公共无效UpdateBmp(){ Log.d(TAG_draw,更新!); 尝试{ INT provazoom = 7; 涂料粉刷=新的油漆(); INT mymapWidth = mapWidth; INT mymapHeight = mapHeight; 如果(mymapWidth> oldW || mymapHeight> oldH || oldW℃,|| oldH℃,){ obstaclesBmpTmp = Bitmap.createBitmap(mymapWidth * provazoom,mymapHeight * provazoom,Bitmap.Config.ARGB_4444); lasti = 0; Log.d(TAG_draw!Cambiate dimensioni+ oldW +CONTRO+ mymapWidth +E+ oldH +CONTRO+ mymapHeight); oldW = mymapWidth; oldH = mymapHeight; } 其他{ Log.d(TAG_draw,Dimensioni uguali!); } Log.d(TAG_draw,parto dall'index+ lasti); 帆布tmpCanvas =新的Canvas(obstaclesBmpTmp); //tmpCanvas.drawColor(Color.DKGRAY); paint.setColor(Color.WHITE); INT corrx = -20; INT科里= 10; 对于(i = lasti; I< obstacles_notordered.size();我++){ 浮动X =(浮点)(((obstacles_notordered.get(I)·X)+ mymapWidth / 2)* provazoom + corrx); 浮动Y =(浮点)(((-1 * obstacles_notordered.get(我).Y)+ mymapHeight / 2)* provazoom +科里); //Log.d(TAG_readFile,trasformo: - 1 * obstacles.get第(i + obstacles.get(ⅰ)·X +e的+ obstacles.get(ⅰ)中的+ X ++(.Y + ).Y)+CON地图WEH+ mapWidth ++ mapHeight); //Log.d(TAG_draw,×E Y+ X ++ Y); tmpCanvas.drawPoint(X,Y,油漆); 油漆PROVA =新的油漆(); prova.setColor(Color.WHITE); lasti =我; //tmpCanvas.drawCircle(x,Y(浮点)1,PROVA); } 同步(obstaclesBmp){ obstaclesBmp = Bitmap.createBitmap(obstaclesBmpTmp); } }赶上(OutOfMemoryError异常E){ Log.e(TAG_error,位图过于格罗萨暗淡:+ mapWidth ++ mapHeight); } } @覆盖 公共无效的run(){ Log.d(TAG_draw,抽屉螺纹Partito); 帆布℃; 而(_run){ C = NULL; 尝试 { C = _surfaceHolder.lockCanvas(空); 同步(_surfaceHolder){ //Log.d(TAG_draw,抽屉螺纹chiama的OnDraw); //Log.d(TAG_draw,抽屉线程公顷IL锁!); UpdateBmp(); _panel.onDraw(C); Log.d(TAG_draw,抽屉螺纹Dorme); 睡眠(500); Log.d(TAG_draw,抽屉螺纹Sveglio); } }赶上(InterruptedException异常E){ // TODO自动生成的catch块 e.printStackTrace(); } 最后 { //这样做的最后,这样,如果抛出一个异常 //上面的过程中,我们不留在表面 //不一致的状态 如果(C!= NULL){ _surfaceHolder.unlockCanvasAndPost(C); } } } //Log.d(TAG_draw,抽屉螺纹termina); }}公共类FileReaderThread继承Thread { 私人布尔_run = FALSE; 公共无效setRunning(布尔运行){ _run =运行; } 公共双模(顶点v){ 返回的Math.sqrt(Math.pow(VX,2)+ Math.pow(VY,2)); } 公共无效insord(顶点dains,LinkedList的<点> LISTA){ // funzione每L'inserimento ordinato在UNA LISTA 的ListIterator<点> I2 = lista.listIterator(); 如果(lista.size()== 0){ lista.add(dains); } 其他{ 而(i2.hasNext()){ 顶点温度= i2.next(); //System.out.println("x达插件+ dains.x +confrontata骗子+ temp.x); //如果(模(温度)==模(dains)及&安培; temp.x == dains.x&安培;&安培; temp.y == dains.y){} 如果(模(临时)> =模(dains)){ lista.add(i2的previousIndex(),dains。); //System.out.println("inserito在posizione+(。i2的previousIndex())); 打破; } 如果(i2.hasNext()== FALSE){ lista.addLast(dains); //System.out.println("inserito在ULTIMA posizione+(。i2的previousIndex()+ 1)); 打破; } } } } 公共无效insord_x(顶点dains,ArrayList的<点> LISTA){ // inserimento ordinato rispetto全部x每条GLI ostacoli 的ListIterator<点> I2 = lista.listIterator(); 如果(lista.size()== 0){ lista.add(dains); } 其他{ 而(i2.hasNext()){ 顶点温度= i2.next(); //System.out.println("x达插件+ dains.x +confrontata骗子+ temp.x); //如果(模(温度)==模(dains)及&安培; temp.x == dains.x&安培;&安培; temp.y == dains.y){} 如果(temp.x> = dains.x){ lista.add(i2的previousIndex(),dains。); //System.out.println("inserito在posizione+(。i2的previousIndex())); 打破; } 如果(i2.hasNext()== FALSE){ lista.add(i2.nextIndex(),dains); //System.out.println("inserito在ULTIMA posizione+(。i2的previousIndex()+ 1)); 打破; } } } } 公共无效的run(){ 而(_run){ Log.d(TAG_readFile,读线程Partito); // istanzio未oggetto二TIPO资源每usare facilmente勒米厄risorse DALLA cartella RES //资源RES = this.getResources(); // Recupero DALLA cartella资源\生IL文件sottoforma迪流E LO trasformo 文件SD卡= Environment.getExternalStorageDirectory(); //获取文本文件 档案文件=新的文件(SD卡,provatesto.g2o); 在的InputStream = NULL; 尝试 { 在=新的BufferedInputStream(新的FileInputStream(文件)); Log.d(TAG_readFile,诺姆文件+ file.getName()); }赶上(FileNotFoundException异常E){ // TODO自动生成的catch块 Log.d(TAG_readFile,FILE非TROVATOOOOOOOO); e.printStackTrace(); } // InputStream的河道= res.openRawResource(R.raw.provatesto); //的DataInputStream解散=新的DataInputStream(河道); 的DataInputStream解散=新的DataInputStream(中); 串线=空; INT vIndex = 0; INT oIndex = 0; // leggo UNA LINEA 尝试 { //Log.d(TAG_readFile,leggo IL文件); 而((行= dis.readLine())!= NULL){ //Log.d(TAG_readFile,读者线程公顷IL锁!); //Log.d(TAG_readFile,何letto拉利内阿:+线); StringTokenizer的ST =新的StringTokenizer(线); //Log.d(TAG_readFile,何letto拉利内阿:+线); 尝试{ 字符串项= st.nextToken(); //Log.d(TAG_readFile,令牌:+条目); 如果(entry.equals(VERTEX_SE2)){ 整数指数=的Integer.parseInt(st.nextToken()); 双X = Double.parseDouble(st.nextToken()); 双Y = Double.parseDouble(st.nextToken()); 双R = Double.parseDouble(st.nextToken()); 顶点newVertex =新顶点(X,Y,vIndex); 同步(图){ map.put(vIndex,newVertex); } 同步(ORIGINALE){ originale.add(newVertex); } 如果(vIndex大于0)map.get(vIndex-1).addEdge(map.get(vIndex)); insord(newVertex,originalPath); //Log.d(TAG_readFile,+ vIndex); vIndex ++; } 否则如果(entry.equals(VERTEX_XY)){ 整数指数=的Integer.parseInt(st.nextToken()); 双X = Double.parseDouble(st.nextToken()); 双Y = Double.parseDouble(st.nextToken()); //Log.d(TAG_readFile,XY索引:+ X ++ Y); 尝试{ 顶点newVertex = obstacles.get(指数); }赶上(IndexOutOfBoundsException异常E){ //obstacles.add(new顶点(Double.parseDouble(x)中,Double.parseDouble(y)的,的Integer.parseInt(索引))); 如果(Math.abs(x)的> mapWidth / 2)mapWidth =(int)的Math.ceil(Math.abs(X))* 2; 如果(Math.abs(y)的> mapHeight / 2)mapHeight =(int)的Math.ceil(Math.abs(γ)* 2); //Log.d(TAG_readFile,mapWidth+ mapWidth +mapHeight+ mapHeight); / * 同步(障碍物){ insord_x(新顶点(X,Y,索引),障碍); } * / 同步(障碍物){ obstacles_notordered.add((新顶点(X,Y,索引))); } } oIndex ++; } 其他{//Log.d(TAG_readFile,边缘); } 如果(oIndex%200 == 0){ Log.d(TAG_readFile,读者线程STA girando); } }赶上(NoSuchElementException异常E){ } //Log.d(TAG_readFile,oindex+ oIndex); } // }赶上(IOException异常E){ Log.e(TAG_readFile,Errore杜兰特LA lettura迪UNA LINEA。); 行=结束; e.printStackTrace(); } Log.d(TAG_readFile,读者线程Termina); }}}}
您也应该不会做任何长期处理您的UI线程,因为它可以阻止它,并给你的ANR例外。因为没有方法来更新从另一个线程,通常使用处理程序
与任何一个发
或UI 的AsyncTask
运行在后台长期的过程,并更新UI线程。
只要看看无痛线程一些的解释,并在有关这一个极好的教程机器人的性能。
I have a thread "reader"
that reads a file and updates a list A. Another thread "drawer"
reads what there is in the variable a, do something, calls ondraw and then sleeps for 500ms (during this time reader populates A).
I have also a preference activity that starts if i press menu button.
The problem is that if i press the button while the reader thread hasn't finished to read his file i have en error in logcat.(see below)
I've seen that the problem is the reader thread that is running while it shows me the preference menu, in fact, if i wait until the reader ends and i click on a preference it all goes well, but if i click while its running igot the error.
How can i handle the threads that are still running when i anewactivity starts? how i "pause"
them? Becouse my file to read can bevery long so i cant wait that reader thread ends.
thanks
EDIT: To be more precise, what appens is that, if i press the menu button, the preferenceActivity starts and i see the correct view (with radio buttons etc) but the problem is when i click on a random point on the screen, it gives me error. If i wait that the read thred ends(i see it from logcat) and then i click on arandom point, it goes everithing well...
logcat error :
02-03 10:18:51.196: ERROR/ActivityManager(66): ANR in it.planningpathapp.ale (it.planningpathapp.ale/.Preferences)
02-03 10:18:51.196: ERROR/ActivityManager(66): Reason: keyDispatchingTimedOut
02-03 10:18:51.196: ERROR/ActivityManager(66): Load: 0.7 / 0.29 / 0.29
02-03 10:18:51.196: ERROR/ActivityManager(66): CPU usage from 13441ms to 36ms ago:
02-03 10:18:51.196: ERROR/ActivityManager(66): ningpathapp.ale: 82% = 75% user + 7% kernel / faults: 6211 minor 1 major
02-03 10:18:51.196: ERROR/ActivityManager(66): adbd: 16% = 0% user + 15% kernel / faults: 36 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): system_server: 11% = 8% user + 3% kernel / faults: 229 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): logcat: 3% = 1% user + 2% kernel
02-03 10:18:51.196: ERROR/ActivityManager(66): m.android.phone: 0% = 0% user + 0% kernel / faults: 33 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): ronsoft.openwnn: 0% = 0% user + 0% kernel / faults: 30 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): m.android.music: 0% = 0% user + 0% kernel / faults: 52 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): id.defcontainer: 0% = 0% user + 0% kernel / faults: 14 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): com.svox.pico: 0% = 0% user + 0% kernel / faults: 15 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): ndroid.launcher: 0% = 0% user + 0% kernel / faults: 18 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): com.android.mms: 0% = 0% user + 0% kernel / faults: 22 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): m.android.email: 0% = 0% user + 0% kernel / faults: 41 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): android.protips: 0% = 0% user + 0% kernel / faults: 15 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): .quicksearchbox: 0% = 0% user + 0% kernel / faults: 34 minor
02-03 10:18:51.196: ERROR/ActivityManager(66): TOTAL: 99% = 72% user + 20% kernel + 1% irq + 6% softirq
02-03 10:18:51.216: WARN/WindowManager(66): No window to dispatch pointer action 1
public class PathPlanningApp1Activity extends Activity {
private static Object lock=new Object();
//Mie tag per il debug mediante LogCat
private static final String TAG_readFile = "READFILE_thread";
private static final String TAG_draw = "DRAW_Thread";
private static final String TAG_error = "ERROR";
private final HashMap < Integer , vertex > map = new HashMap < Integer , vertex> ();
private final LinkedList < vertex > originalPath = new LinkedList < vertex > ();
private final LinkedList < vertex > originale = new LinkedList < vertex > ();
private final ArrayList < vertex > obstacles = new ArrayList<vertex>();
private final ArrayList < vertex > obstacles_notordered = new ArrayList<vertex>();
private int mapWidth=1;
private int mapHeight=1;
Panel panel;
Resources res;
private Bitmap mBitmap;
private Bitmap obstaclesBmp=Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
private float zoom=15;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
res= this.getResources() ;
panel=new Panel(this);
setContentView(panel);
Log.d(getLocalClassName(), "ON CREATE");
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
protected void onResume()
{Log.d(getLocalClassName(), "ON RESUME");
setContentView(panel);
super.onResume();
}
protected void onDestroy(){
Log.d(getLocalClassName(), "ON DESTROY");
super.onDestroy();
}
protected void onPause(){
Log.d(getLocalClassName(), "ON PAUSE");
Log.d(getLocalClassName(), "stato drawer" +panel.drawerThread.getState());
Log.d(getLocalClassName(), "stato frt" +panel.frt.getState());
super.onPause();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.ic_launcher: Toast.makeText(this, "You pressed the icon!", Toast.LENGTH_LONG).show();
Intent settingsActivity = new Intent(this,Preferences.class);
startActivity(settingsActivity);
break;
case R.id.text: Toast.makeText(this, "You pressed the text!", Toast.LENGTH_LONG).show();
break;
case R.id.icontext: Toast.makeText(this, "You pressed the icon and text!", Toast.LENGTH_LONG).show();
break;
}
return true;
}
class Panel extends SurfaceView implements SurfaceHolder.Callback{
FileReaderThread frt=new FileReaderThread();
DrawerThread drawerThread ;
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
drawerThread = new DrawerThread(getHolder() , this );
setDrawingCacheEnabled(true);
setFocusable(true);
}
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
try{
int i=0;
int height=canvas.getHeight();
int width=canvas.getWidth();
Paint paint = new Paint();
paint.setColor(Color.GREEN);
//Log.d(TAG_draw, " obstaclesBmp="+obstaclesBmp.getHeight());
if (obstaclesBmp != null){
synchronized(obstaclesBmp){
canvas.drawBitmap(obstaclesBmp, 0, 0, null);
}
}
}catch(OutOfMemoryError e){
Log.e(TAG_error, "ONDRAW !!Bitmap troppo grossa !dim:"+mapWidth+" "+mapHeight);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
if(frt.getState()== Thread.State.TERMINATED){
//frt = new FileReaderThread();
// frt.start();
// <-- added fix
}else {
Log.d(TAG_readFile," stato frt "+frt.getState());
frt.setRunning(true);
frt.start();
}
if(drawerThread.getState()==Thread.State.TERMINATED){
drawerThread = new DrawerThread(getHolder() , this );
drawerThread.setRunning(true);
drawerThread.start();
}
else{
drawerThread.setRunning(true);
drawerThread.start();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
drawerThread.setRunning(false);
while (retry) {
try {
drawerThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
retry = true;
frt.setRunning(false);
while (retry) {
try {
frt.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
public class DrawerThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
Bitmap oldbmp=null;
Bitmap newbmp=null;
Bitmap obstaclesBmpTmp = null;
int i=0;
int lasti=0;
int oldW=-1,oldH=-1;
public DrawerThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
public void UpdateBmp(){
Log.d(TAG_draw, "Update!");
try{
int provazoom=7;
Paint paint = new Paint();
int mymapWidth=mapWidth;
int mymapHeight=mapHeight;
if(mymapWidth>oldW || mymapHeight>oldH ||oldW<0 || oldH<0 ){
obstaclesBmpTmp=Bitmap.createBitmap(mymapWidth*provazoom,mymapHeight*provazoom, Bitmap.Config.ARGB_4444 );
lasti=0;
Log.d(TAG_draw, "Cambiate dimensioni! "+oldW+" contro "+mymapWidth+" e "+oldH+" contro"+mymapHeight);
oldW=mymapWidth;
oldH=mymapHeight;
}
else{
Log.d(TAG_draw, "Dimensioni uguali! ");
}
Log.d(TAG_draw, "parto dall'index "+lasti);
Canvas tmpCanvas=new Canvas(obstaclesBmpTmp);
//tmpCanvas.drawColor(Color.DKGRAY);
paint.setColor(Color.WHITE);
int corrx=-20;
int corry=10;
for(i=lasti;i<obstacles_notordered.size();i++){
float x=(float)( ( (obstacles_notordered.get(i).x) +mymapWidth/2 )*provazoom +corrx );
float y=(float)( ( (-1*obstacles_notordered.get(i).y) +mymapHeight/2 )*provazoom +corry );
//Log.d(TAG_readFile, "trasformo : "+obstacles.get(i).x+" e "+obstacles.get(i).y+" in "+x+" "+(-1*obstacles.get(i).y)+"con map w e h"+mapWidth+" "+mapHeight);
//Log.d(TAG_draw, "x e y "+x+" "+y);
tmpCanvas.drawPoint(x,y, paint);
Paint prova=new Paint();
prova.setColor(Color.WHITE);
lasti=i;
//tmpCanvas.drawCircle(x, y, (float)1, prova);
}
synchronized(obstaclesBmp){
obstaclesBmp=Bitmap.createBitmap(obstaclesBmpTmp);
}
}catch(OutOfMemoryError e){
Log.e(TAG_error, "Bitmap troppo grossa !dim:"+mapWidth+" "+mapHeight);
}
}
@Override
public void run() {
Log.d(TAG_draw, "Drawer Thread Partito");
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
//Log.d(TAG_draw, "Drawer Thread chiama onDraw");
//Log.d(TAG_draw, "Drawer Thread ha il lock !");
UpdateBmp();
_panel.onDraw(c);
Log.d(TAG_draw, "Drawer Thread Dorme");
sleep(500);
Log.d(TAG_draw, "Drawer Thread Sveglio");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
//Log.d(TAG_draw, "Drawer Thread termina");
}
}
public class FileReaderThread extends Thread {
private boolean _run = false;
public void setRunning(boolean run) {
_run = run;
}
public double modulo (vertex v){
return Math.sqrt(Math.pow(v.x,2)+Math.pow(v.y,2)) ;
}
public void insord(vertex dains,LinkedList<vertex> lista){
//funzione per l'inserimento ordinato in una lista
ListIterator<vertex> i2=lista.listIterator();
if(lista.size()==0){
lista.add(dains);
}
else{
while(i2.hasNext()){
vertex temp=i2.next();
//System.out.println("x da ins "+dains.x+" confrontata con "+temp.x);
//if(modulo(temp)==modulo(dains)&& temp.x==dains.x && temp.y==dains.y){ }
if(modulo(temp)>=modulo(dains)){
lista.add(i2.previousIndex(), dains);
//System.out.println("inserito in posizione "+(i2.previousIndex()));
break;
}
if(i2.hasNext()==false){
lista.addLast(dains);
//System.out.println("inserito in ultima posizione "+(i2.previousIndex()+1));
break;
}
}
}
}
public void insord_x(vertex dains,ArrayList<vertex> lista){
//inserimento ordinato rispetto alle x per gli ostacoli
ListIterator<vertex> i2=lista.listIterator();
if(lista.size()==0){
lista.add(dains);
}
else{
while(i2.hasNext()){
vertex temp=i2.next();
//System.out.println("x da ins "+dains.x+" confrontata con "+temp.x);
//if(modulo(temp)==modulo(dains)&& temp.x==dains.x && temp.y==dains.y){ }
if(temp.x>=dains.x){
lista.add(i2.previousIndex(), dains);
//System.out.println("inserito in posizione "+(i2.previousIndex()));
break;
}
if(i2.hasNext()==false){
lista.add(i2.nextIndex(),dains);
//System.out.println("inserito in ultima posizione "+(i2.previousIndex()+1));
break;
}
}
}
}
public void run(){
while (_run) {
Log.d(TAG_readFile, "Reader Thread Partito");
//istanzio un oggetto di tipo Resources per usare facilmente le mie risorse dalla cartella Res
//Resources res = this.getResources() ;
//Recupero dalla cartella res\raw il file sottoforma di stream e lo trasformo
File sdcard = Environment.getExternalStorageDirectory();
//Get the text file
File file = new File(sdcard,"provatesto.g2o");
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
Log.d(TAG_readFile, "nome file "+file.getName());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
Log.d(TAG_readFile, "FILE NON TROVATOOOOOOOO");
e.printStackTrace();
}
//InputStream instream = res.openRawResource(R.raw.provatesto);
//DataInputStream dis = new DataInputStream(instream);
DataInputStream dis = new DataInputStream(in);
String line= "empty";
int vIndex = 0;
int oIndex = 0;
//leggo una linea
try {
//Log.d(TAG_readFile, "leggo il file");
while((line = dis.readLine()) != null){
//Log.d(TAG_readFile, "Reader Thread ha il lock!!");
//Log.d(TAG_readFile, "Ho letto la linea: "+line);
StringTokenizer st= new StringTokenizer( line );
//Log.d(TAG_readFile, "Ho letto la linea: "+line);
try{
String entry=st.nextToken();
//Log.d(TAG_readFile, "Token: "+entry);
if(entry.equals("VERTEX_SE2")){
Integer index = Integer.parseInt(st.nextToken());
Double x = Double.parseDouble(st.nextToken());
Double y = Double.parseDouble(st.nextToken());
Double r = Double.parseDouble(st.nextToken());
vertex newVertex=new vertex(x,y,vIndex);
synchronized(map){
map.put(vIndex, newVertex);
}
synchronized(originale){
originale.add(newVertex);
}
if(vIndex>0) map.get(vIndex-1).addEdge(map.get(vIndex));
insord(newVertex,originalPath);
//Log.d(TAG_readFile, ""+vIndex);
vIndex++;
}
else if(entry.equals("VERTEX_XY")){
Integer index = Integer.parseInt(st.nextToken());
Double x = Double.parseDouble(st.nextToken());
Double y = Double.parseDouble(st.nextToken());
//Log.d(TAG_readFile, "xy index: "+x+" "+y);
try{
vertex newVertex=obstacles.get(index);
}catch(IndexOutOfBoundsException e){
//obstacles.add(new vertex(Double.parseDouble(x),Double.parseDouble(y),Integer.parseInt(index)));
if(Math.abs(x)>mapWidth/2) mapWidth=(int)Math.ceil(Math.abs(x))*2;
if(Math.abs(y)>mapHeight/2) mapHeight=(int)Math.ceil(Math.abs(y)*2);
//Log.d(TAG_readFile, "mapWidth "+mapWidth+" mapHeight "+mapHeight);
/*
synchronized(obstacles){
insord_x(new vertex(x,y,index),obstacles);
}
*/
synchronized(obstacles){
obstacles_notordered.add((new vertex(x,y,index)));
}
}
oIndex++;
}
else {//Log.d(TAG_readFile, "edge");
}
if(oIndex%200==0){
Log.d(TAG_readFile, "Reader thread sta girando");
}
}catch(NoSuchElementException e){
}
//Log.d(TAG_readFile, "oindex "+oIndex);
}//
} catch (IOException e) {
Log.e(TAG_readFile, "Errore durante la lettura di una linea.");
line= "end";
e.printStackTrace();
}
Log.d(TAG_readFile, "Reader Thread Termina");
}}
}
}
you also should not do any long term processing in your UI thread as it may block it and give you the ANR exception. as there is no way to update the UI from another thread it is common to use a Handler
with either a Thread
or AsyncTask
to run the long term processes in the background and update the UI thread.
just look at painless threading for some explaination and at android performance for an excellent tutorial on this one.
这篇关于Android的 - 如何在另一个活动暂停线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!