Android编程新手:程序没有响应

时间:2016-04-25 17:18:42

标签: java android

我是Android编程新手,我已经开始学习一些小程序了。这个绘图程序直到我划出很多行(我不知道多少但大约10-20)这个数字取决于我绘制它的速度有多快(绘制更少的线条以便卡住)。当我开始调试并停止响应它停止响应时,它引导我到这一行:

private native void nativePollOnce(long ptr, int timeoutMillis); /non-static for callbacks/

不知道它是什么,是什么冻结程序,但这是我的程序:

Drawing.java

package com.appl.nikola.drawing;

import android.graphics.Color;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Drawing extends AppCompatActivity implements View.OnTouchListener, SurfaceHolder.Callback {

    public static SurfaceView surfaceView;
    public static SurfaceHolder surfaceHolder;
    Thread t1;
    public static Coordinates cordinates;
    public static List<Coordinates> listOfDrawing;
    int staCrta;
    public static Paint p;
    public static boolean isItOK;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drawing);
        //Definisem surfaceView
        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        surfaceView.setOnTouchListener(this);
        //Definisem surfaceHolder
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        //Definisem listu crtanja
        listOfDrawing = new ArrayList<Coordinates>();
        //Coordinates = {vrsta objekta:1-linija, 2-rucno, 3- pravougaonik, x1, y1, x2, y2}
        cordinates = new Coordinates();
        staCrta = 1;
        cordinates.x1 = 5;
        cordinates.x2 = 5;
        cordinates.y1 = 6;
        cordinates.y2 = 6;
        cordinates.vrstaCrtanja = 1;

        listOfDrawing.add(new Coordinates(cordinates.vrstaCrtanja,cordinates.x1,cordinates.y1,cordinates.y1,cordinates.y2));
        cordinates.x1 = 7;
        cordinates.x2 = 7;
        cordinates.y1 = 8;
        cordinates.y2 = 8;
        cordinates.vrstaCrtanja = 1;
        listOfDrawing.add(new Coordinates(cordinates.vrstaCrtanja,cordinates.x1,cordinates.y1,cordinates.y1,cordinates.y2));
        //Definisem Paint: boja debljina
        p = new Paint();
        p.setColor(Color.YELLOW);
        p.setStrokeWidth(3);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                switch (staCrta){
                    case 1:
                        cordinates.vrstaCrtanja = 1;
                        cordinates.x1 = event.getX();
                        cordinates.y1 = event.getY();
                        Log.d("Log1","Touch down");
                        break;
                    case 2:

                        break;
                    case 3:

                        break;
                }
                break;
            case MotionEvent.ACTION_UP:
                switch (staCrta){
                    case 1:
                        cordinates.x2 = event.getX();
                        cordinates.y2 = event.getY();
                        listOfDrawing.add(new Coordinates(cordinates.vrstaCrtanja,cordinates.x1,cordinates.y1,cordinates.x2,cordinates.y2));
                        Log.d("Log1", "Touch up");
                        break;
                    case 2:

                        break;
                    case 3:

                        break;
                }
                break;
            case MotionEvent.ACTION_MOVE:

                switch (staCrta){
                    case 1:

                        break;
                    case 2:

                        break;
                    case 3:

                        break;
                }
                break;
        }
        return true;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //Kada je surfaceView definisi i kreiraj thread t1
        isItOK = true;
        t1 = new Thread(new DrawingSurfaceLayout());
        t1.start();
        Log.d("Log1", "SurfaceCreated");
        Log.d("Log1",Boolean.toString(isItOK));
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
            isItOK = false;
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t1 = null;
        Log.d("Log1","Thread Stopped");
    }



}

DrawingSurfaceLayout.java

package com.appl.nikola.drawing;

import android.graphics.Canvas;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Nikola on 4/25/2016.
 */
public class DrawingSurfaceLayout implements Runnable {
    Canvas c;
    Drawing drawing;
    public DrawingSurfaceLayout() {
        drawing = new Drawing();

    }

    @Override
    public void run() {

        try{
            Log.d("Log1","run");
            Log.d("Log1",Boolean.toString(drawing.isItOK));
            while(drawing.isItOK){
                if(!drawing.surfaceHolder.getSurface().isValid()){
                    Log.d("Log1","Surface not valid");
                    continue;
                }

                c = drawing.surfaceHolder.lockCanvas();
                c.drawRGB(0, 0, 255);
                List<Coordinates> listOfDrawing;
                listOfDrawing = new ArrayList<Coordinates>();
                listOfDrawing = drawing.listOfDrawing;
                for(Coordinates x: listOfDrawing){
                    if(x.vrstaCrtanja == 1){//Linija
                        c.drawLine(x.x1,x.y1,x.x2,x.y2,drawing.p);
                    }
                }
                drawing.surfaceHolder.unlockCanvasAndPost(c);

            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }


}

Coordinates.java

package com.appl.nikola.drawing;

/**
 * Created by Nikola on 4/25/2016.
 */
public class Coordinates {
    float vrstaCrtanja;
    float x1;
    float y1;
    float x2;
    float y2;
    public Coordinates() {

    }
    public Coordinates(float vrstaCrtanja, float x1, float y1, float x2, float y2) {
        this.vrstaCrtanja = vrstaCrtanja;
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
    }
}

activity_drawing.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.appl.nikola.drawing.Drawing"
    android:weightSum="100"
    android:orientation="vertical">

    <SurfaceView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="95"
        android:id="@+id/surfaceView"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="5"
        android:id="@+id/bMenu"/>

</LinearLayout>

编辑:

根据要求,这是我重现错误时弹出的内容

04-25 21:52:21.091: W/System.err(2488): java.util.ConcurrentModificationException
04-25 21:52:21.093: W/System.err(2488):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
04-25 21:52:21.093: W/System.err(2488):     at com.appl.nikola.drawing.DrawingSurfaceLayout.run(DrawingSurfaceLayout.java:37)
04-25 21:52:21.093: W/System.err(2488):     at java.lang.Thread.run(Thread.java:818)

是的,当我点击主页按钮时弹出(应用冻结时回家)

04-25 21:57:07.227: I/ActivityManager(1533): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.android.launcher3/.Launcher (has extras)} from uid 1000 on display 0
04-25 21:57:07.243: D/(1533): HostConnection::get() New Host Connection established 0x9e2eb9a0, tid 1570
04-25 21:57:07.255: E/EGL_emulation(1187): tid 1187: eglCreateSyncKHR(1294): error 0x3004 (EGL_BAD_ATTRIBUTE)
04-25 21:57:07.305: I/InputDispatcher(1533): Dropping event because there is no touchable window at (195, 525).
04-25 21:57:07.357: W/EGL_emulation(2262): eglSurfaceAttrib not implemented
04-25 21:57:07.357: W/OpenGLRenderer(2262): Failed to set EGL_SWAP_BEHAVIOR on surface 0xa31bf620, error=EGL_SUCCESS
04-25 21:57:07.936: W/OpenGLRenderer(2262): Incorrectly called buildLayer on View: ShortcutAndWidgetContainer, destroying layer...
04-25 21:57:07.936: W/OpenGLRenderer(2262): Incorrectly called buildLayer on View: ShortcutAndWidgetContainer, destroying layer...

2 个答案:

答案 0 :(得分:0)

在run()方法的DrawingSurfaceLayout中,您需要访问drawing.listOfDrawing,而另一个线程正在填充它。您可以使用迭代器来避免此问题。替换这个:

for(Coordinates x: listOfDrawing){
                if(x.vrstaCrtanja == 1){//Linija
                    c.drawLine(x.x1,x.y1,x.x2,x.y2,drawing.p);
                }
            }

用这个:

for (Iterator<Coordinates> it = listOfDrawing.iterator(); it.hasNext();){
                Coordinates x = it.next();
                if (x.vrstaCrtanja == 1) {
                     it.drawLine(x.x1,x.y1,x.x2,x.y2,drawing.p);
                }
            }

它应该有效(我无法测试)。

答案 1 :(得分:0)

感谢您的帮助,我不知道多线程是如何工作的,但是这是我如何解决问题。我在同一个地方同步线程我使用相同的变量而不是:

listofDrawing = drawing.listofDrawing;

我设置了这个

synchronized (drawing.listOfDrawing){
                    for(Coordinates x: drawing.listOfDrawing){
                        listOfDrawing.add(x);
                    }

                }

它就像一个魅力。我把这个答案放在一边,这样可能对某人有帮助。