Domanda

Ho un database pieno di record nel seguente formato:. Quello che voglio la mia domanda da fare è selezionare i record da un database esterno, e visualizzare i record sullo schermo del telefono utilizzando un SurfaceView.

Al momento, ho un'attività, e un servizio responsabile per la parte di registrazione di raccolta dell'applicazione. L'attività passa l'intento di Servizio, e da visualizzare le risponde di servizio restituendo i record che hanno bisogno. I record vengono memorizzati nel mio programma come istanze della classe di dati, e si limita a disporre lo schermo coordinate del luogo in cui l'elemento deve essere disegnata nella vista (io sono solo disegnare un cerchio per ogni record nel DB).

Per ragioni di brevità, io non includere il servizio, ma io includere uno scheletro della classe di attività e dei dati che desidero di visualizzazione.

public class Data{
    private int x;
    private int y;
    private int id;
    private int shape;

    /*
    * Getters and setters for class properties
    */
}

public class Displayer extends Activity {
    int ht;
    int wt;
    dataReceiver dreceiver; 
    public static Map<String, Data> Info; 
    private LinearLayout linear; 
    private static final int RADIUS = 20;
    Panel panel;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        panel=new Panel(this);
        setContentView(panel);

        Intent scv = new Intent(this, DataService.class);
        startService(scv);
    }
    /*
    * Various other methods to take care of onDestroy, onPause, etc.
    */

    public class dataReceiver extends BroadcastReceiver {
        //Get new data from intents sent by the Service and store it in Info variable

        //Update the Testing Map data-structure in the Panel SurfaceView with new records
        panel.setData(Info);

    }
}

Il problema che sto avendo riguarda i SurfaceView. Mi rendo conto che molte persone stanno andando a suggerire che io uso solo un normale vista, ma la mia domanda comporta un sacco di elementi, in modo da un SurfaceView sarebbe molto più adatto per le mie esigenze. Di seguito è riportato uno scheletro della mia classe SurfaceView che contiene una classe annidata per gestire i thread.

public class Panel extends SurfaceView implements SurfaceHolder.Callback {
    private PanelThread _thread;

    private Paint circlepaint;
    private Paint textpaint;

    private static int CircleColor = Color.YELLOW;
    private static int TextColor = Color.RED;
    private static Map<String, Data> Testing;

    public Panel(Context context, Map<String, Data> entries) {
        super(context);

        getHolder().addCallback(this);
        _thread = new PanelThread(getHolder(), this);
        setFocusable(true);

        textpaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textpaint.setStyle(Style.FILL_AND_STROKE);
        textpaint.setColor(TextColor);

        Testing = new HashMap<String, Data>();
        // Log.d("TestingSize",String.valueOf(Testing.size()));
        if (!(Testing.isEmpty())) {
            Testing.clear();
        }

        for (Map.Entry<String, Data> e : entries.entrySet()) {
            String keyvalue = e.getKey();
            Data v = e.getValue();
            Panel.Testing.put(keyvalue, v);
        }

    }

    public Panel(Context context) {
        super(context);
        getHolder().addCallback(this);
        _thread = new PanelThread(getHolder(), this);
        setFocusable(true);
        textpaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textpaint.setStyle(Style.FILL_AND_STROKE);
        textpaint.setColor(TextColor);
        Testing = new HashMap<String, Victims>();

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // TODO Auto-generated method stub
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        _thread.setRunning(true);
        _thread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        /* we have to tell thread to shut down 
        * & wait for it to finish, 
        * or else it might touch the Surface 
        * after we return and explode
        */

        boolean retry = true;
        _thread.setRunning(false);
        while (retry) {
            try {
                _thread.join();
                retry = false;
            } catch (InterruptedException e) {
                // we will try it again and again...
            }
        }
    }   
    /*If new records are received 
    * from the service, they can be updated 
    * using this method
    */
    public void setData(Map<String,Data>Info){
        Testing=Info;
    }

    /*
    * Iterate over all contents of Testing List and display them to the screen
    */
    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (!(Testing.isEmpty())) {
            for (Map.Entry<String, Victims> e : Testing.entrySet()) {
                Data d = e.getValue();      
                canvas.drawCircle(d.getX(), d.getY(), 10, circlepaint);
            }
        }

        canvas.save();
        canvas.restore();
    }

    /*
    * Nested class to manage the threads for the SurfaceView
    */
    class PanelThread extends Thread {
        private SurfaceHolder _surfaceHolder;
        private Panel _panel;
        private boolean _run = false;

        public PanelThread(SurfaceHolder surfaceHolder, Panel panel) {
            _surfaceHolder = surfaceHolder;
            _panel = panel;
        }

        public void setRunning(boolean run) {
            _run = run;
        }

        public SurfaceHolder getSurfaceHolder() {
            return _surfaceHolder;
        }

        @Override
        public void run() {
            Canvas c;
            while (_run) {
                c = null;
                try {
                    c = _surfaceHolder.lockCanvas(null);
                    synchronized (_surfaceHolder) {
                        _panel.onDraw(c);
                    }
                } 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);
                    }
                }
            }
        }
    }//end of PanelThread

}//end of Panel

Il problema che sto avendo è che una volta che faccio la chiamata iniziale alla classe Panel, ho intenzione di essere sempre nuovi record dal servizio e, di conseguenza, il mio Info Mappa struttura di dati sta per arrivare aggiornato . Tuttavia, la mia classe Panel appena si blocca in un ciclo e non riceve mai oggetti nuovi dati. Tutti gli esempi di SurfaceViews ho trovato avere aggiornamento coinvolti loro metodi all'interno della classe SurfaceView in sé (per esempio toccando lo schermo e la creazione di una nuova immagine, ecc) Purtroppo, sto perplesso su questo particolare problema. Esiste un approccio migliore per la progettazione mia attività / interazione SurfaceView? È un ulteriore View richiesta?

È stato utile?

Soluzione

Da una rapida occhiata al vostro codice Credo che il problema è che si sta tentando di aggiornare una struttura di dati dal thread dell'interfaccia utente, mentre agendo su di esso nella PanelThread. Sembra inoltre che la classe di attività e del pannello sono anche fuori sincrono -. Non vedo il metodo setData nella classe Panel, ma suppongo che aggiorna la variabile membro static test

I miei suggerimenti:

1 - Test non deve essere statica - è fondamentalmente associato a questa istanza della classe.  2 - Utilizzare Sincronizza quando si tocca il dato (Testing). Questo dovrebbe essere fatto sia per l'impostazione e la lettura dei dati.  3 - Mettere un sonno o di una chiamata di attesa nel ciclo corsa - questo dà il tempo per il thread attività di interfaccia utente per l'aggiornamento Testing. salva anche batteria e ti permette di scegliere un frame rate per gli aggiornamenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top