У меня есть поток "reader"
, который читает файл и обновляет список A. Другой поток "drawer"
читает то, что есть в переменной a, что-то делает, вызывает ondraw и затем спит в течение 500 мс (в течение этого времени читатель заполняется A).
У меня также есть действие с предпочтениями, которое начинается, если я нажимаю кнопку меню.
Проблема в том, что если я нажму кнопку, пока поток чтения не завершит чтение его файла, у меня возникнет ошибка в logcat. (См. Ниже)
Я видел, что проблема в том, что поток чтения работает, пока он показывает мне меню настроек, на самом деле, если я жду, пока закончится чтение, и нажимаю на предпочтение, все будет хорошо, но если я нажму пока он работает igot ошибка.
Как я могу обработать потоки, которые все еще работают, когда начинается новая активность? как я "pause"
их? Поскольку мой файл для чтения может быть очень длинным, поэтому я не могу дождаться окончания чтения.
спасибо
РЕДАКТИРОВАТЬ: если быть более точным, то, что происходит, что, если я нажимаю кнопку меню, запускается preferenceActivity, и я вижу правильный вид (с переключателями и т. Д.), Но проблема заключается в том, когда я нажимаю на случайную точку на экран, это дает мне ошибку. Если я подожду, пока закончится чтение, (я вижу это из logcat), а затем нажму на случайную точку, она будет хорошо работать ...
ошибка logcat:
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");
}}
}
}