I have a problem that I can not solve and it is as follows:
In the application I use SugarORM for data persistence and the Httpd Class to implement an http server that listens to requests that will modify the data of the application.
Element model that is managed:
public class Elemento extends SugarRecord implements Serializable {
@Column(name = "Nombre") private String Nombre;
@Column(name = "Active") private boolean Active;
@Column(name = "Categoria") private int Categoria;
public Elemento(){
}
public Elemento(String nombre, boolean active, int categoria) {
Nombre = nombre;
Active = active;
Categoria = categoria;
}
//...getters,setters....//
The main class that manages the user interface, data loading and server initialization is the following:
public class ControlElemento extends Activity {
private List<Elemento> elementos;
HttpdServer server;
private Activity thisActivity;
ArrayAdapter<Elemento> elementosAdapter;
boolean isServerConected = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_control_elemento);
thisActivity = this;
SugarContext.init(thisActivity);
this.cargaDatos();
elementosAdapter = new ElementosAdapter(this, elementos);
ListView lstElementos = (ListView) findViewById(R.id.lstElementos);
lstElementos.setAdapter(elementosAdapter);
if(!isServerConected){
try {
initServer();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
protected void onResume(){
try {
super.onResume();
this.cargaDatos();
if(!isServerConected){
initServer();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy(){
super.onDestroy();
server.stop();
isServerConected = false;
finish();
}
public void cargaDatos(){
elementos= Elemento.findWithQuery(Elemento.class, "Select * from Elemento where categoria = 1");
}
private void initServer() throws Exception {
new Handler().post(new Runnable() {
@Override
public void run() {
try {
server = HttpdServer.getServer();
if(!server.isAlive()){
server.start();
}
isServerConected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public class ElementosAdapter extends ArrayAdapter<Elemento> {
private Context context;
private List<Elemento> elementos;
public ElementoAdapter(Context context, List<Elemento> elementos){
super(context, R.layout.layout_control_elemento, elementos);
this.context = context;
this.elementos= elementos;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View item = inflater.inflate(R.layout.layout_elemento_item, null);
TextView nomElemento = (TextView) item.findViewById(R.id.txtNomElemento);
nomElemento.setText(elementos.get(position).getNombre());
Switch switchElemento = (Switch) item.findViewById(R.id.isActiveElemento);
switchElemento.setChecked(elementos.get(position).isActive());
switchElemento.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
elementos.get(position).setActive(b);
elementos.get(position).save();
}
});
return item;
}
}
The class that implements the server is the following:
public class HttpdServer extends NanoHTTPD {
private static HttpdServer server = null;
private List<Elemento> elementos;
@Override
public Response serve(IHTTPSession session) {
try {
Map<String, String> files = new HashMap<String, String>();
session.parseBody(files);
String postBody = files.get("postData").replace("\n\t","").replace("\n","");
JSONObject info = new JSONObject((postBody));
String hostElemento = session.getHeaders().get("http-client-ip");
int stateUpdate = Integer.parseInt(info.get("STATE").toString());
// Recogemos elemento y modificamos
elementos= Elemento.findWithQuery(Elemento.class, "Select * from Elemento where categoria = 1");
if(stateUpdate == 1){
elementos[0].setActive(true);
}else{
elementos[0].setActive(false);
}
elementos[0].save();
isChanged = true;
String msg = "OK";
return new Response( msg );
} catch (IOException | ResponseException e) {
e.printStackTrace();
return new Response( "NOK: Error retrieving POST Data" );
} catch (JSONException e) {
e.printStackTrace();
return new Response( "NOK: Parse POST body to a JSON error" );
}
}
private HttpdServer() throws IOException {
super(8080);
}
// This static method let you access the unique instance of your server class
public static HttpdServer getServer() throws IOException{
if(server == null){
server = new HttpdServer();
}
return server;
}
public static String getBody(InputStream inputStream) throws IOException {
String body = null;
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
return body;
}
}
Layouts are basically a listview that houses an item layout that contains a switch that takes the name and status of the element through an arrayAdapter.
The operation of receiving the request with the state to be modified and then saving it in the database works perfectly.
What I want to do and I'm not getting it:
* Que después de guardar la modificación del elemento en base de datos me actualice la vista con el nuevo cambio
* A ser posible que mientras este gestionando una petición que haya recibido el servidor aparezca en la vista un dialogo de "Sincronizando", se como definir y mostrar un dialogo de esas características sin embargo al instanciar el servidor en un hilo diferente tengo problemas.
I hope you have understood the context of the application and my doubts.
thank you very much!.
Issue 1: Since I have not received any response after a week, I will try to be clearer by expressing the problem.
A main activity that is the one that manages the UI (as usual), instance within a sub-thread a request server implementing the class link to be able to manage http requests.
This class link , defines a method to treat these http requests and act accordingly by modifying the database.
What I have just summarized in the two previous points works perfectly.
The problem is now:
If I try to modify the view by updating arrayAdapters to collect the changes made to the database, I get an error because it is the thread of the httpd class that makes the modifications and does not allow changes to be made in the view.
The same problem I have if I want to show a load dialog while doing operations on the thread that manages http requests to modify the app database.