У меня есть база данных, заполненная записями в следующем формате:.Я хочу, чтобы мое приложение выбирало записи из внешней базы данных и отображало эти записи на экране телефона с помощью SurfaceView.
В настоящее время у меня есть активность и служба, отвечающая за сбор данных в приложении.Деятельность передает намерение в службу, и служба отвечает, возвращая записи, которые должны быть отображены.Записи хранятся в моей программе как экземпляры класса Data, и у них просто есть экранные координаты того, где элемент должен быть нарисован в представлении (я просто рисую круг для каждой записи в БД).
Ради краткости я не буду включать службу, но включу скелет класса Activity и данные, которые я хочу отобразить.
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);
}
}
Проблема в том, чтоЯ имею отношение к SurfaceView.Я понимаю, что многие люди предложат мне использовать только обычный вид, но мое приложение включает в себя множество элементов, поэтому SurfaceView будет гораздо более подходящим для моих нужд.Ниже приведен скелет моего класса SurfaceView, который содержит вложенный класс для управления потоками.
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
Проблема, с которой я сталкиваюсь, заключается в том, что, как только я сделаю первоначальный вызов класса Panel, ябудет получать новые записи от службы, и, следовательно, моя структура данных Info Map будет обновляться.Однако мой класс Panel просто зацикливается и никогда не получает никаких новых объектов Data.Все примеры SurfaceViews, которые я обнаружил, включали обновление их методов внутри самого класса SurfaceView (например, касание экрана и создание нового изображения и т. Д.) К сожалению, я озадачен этой конкретной проблемой.Есть ли лучший подход для проектирования моего взаимодействия Activity / SurfaceView?Требуется ли дополнительный просмотр?