2016-04-25 26 views
0

私はAndroidプログラミングには新しく、学習するためのいくつかの小さなプログラムを開始しました。このプログラムは、多くの行を描画するまで(私はどれくらい多くは10-20であるか分かりません)、その数は描画の速さによって決まります。Androidプログラミングの新機能:プログラムは応答しません

ドローイング:

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

いけないプログラムがフリーズするもの、しかしここに私のプログラムであること、それが何であるかを知っているし、次のとおりです。私は、デバッグおよび停止プログラムを起動するとときに、それは、この行に私をリード応答を停止.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... 
+0

monitor/logcatログを追加した場合に役立ちます。 – pushasha

+0

お返事ありがとうございます。私はAndroidプログラミングには本当に新しいので、それらのログがどこにあるか、どこにあるのかはわかりません – Nikola010

+0

[こちらはAndroidのdocsページへのリンクです](http://developer.android.com/tools/help /monitor.html)にアクセスしてください。あなたはそれが働いている、あなたのデバイス上でアプリケーションを実行することができますし、コンピュータに接続されている限り(またはエミュレータを使用している場合)、アプリケーションログを "logcat"またはモニターツールのDDMSセクション。 – pushasha

答えて

0

run()メソッドのDrawingSurfaceLayoutでは、別のスレッドがデータを入力している間にdrawing.listOfDrawingにアクセスするようになります。イテレータを使用してこの問題を回避できます。それが動作するはずです

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

(私はテストすることはできません)。これで

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

:これを交換してください。

0

助けてくれてありがとう、私はマルチスレッドの仕組みを知らなかったが、ここでどのように問題を管理したのか分かっている。私はそれは魔法のように動作し、この

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

       } 

を設定

listofDrawing = drawing.listofDrawing; 

:私は、私は同じ変数を使用する唯一の場所でスレッドを同期され、代わりに。私は誰かを助けるかもしれないので、私はこの答えを置きます。