Android事件通过UI服务和异步任务
我的用户界面创建服务和服务创建线程。 我需要改变UI中的异步风格的事件。Android事件通过UI服务和异步任务
我曾尝试广播,但这导致我的应用程序崩溃。因为我无法连接正确的内容。
我该怎么做?
编辑,添加一些示例代码:
主界面:
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{ // Constructor.
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
LocalBroadcastManager.getInstance(this).registerReceiver(eventCfgCompleta,
new IntentFilter(Constants.CFG_COMPLETA));
Intent intentMemoryService = new Intent(
getApplicationContext(), mw_service.class);
startService(intentMemoryService);
}
private BroadcastReceiver eventCfgCompleta = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent){
// Get extra data included in the Intent
// Si la app tiene cfg, pasa a ActivityConectandoMW
Intent intent_activity = new Intent(context, ActivityConectandoMW.class);
intent_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent_activity);
}
};
}
服务:
public class mw_service extends Service
{
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
Log.d(TAG, "Servicio creado...");
sendMessage("ON CREATE SERVICE");
}
@Override
public int onStartCommand(Intent intent, int flags, int startID)
{
Log.d(TAG, "Servicio onStart...");
conex = new conexion_thread(getApplicationContext(),
MWserial,
MWpassword,
casilla,
webkey);
conex.execute();
}
return START_STICKY;
}
@Override
public void onDestroy()
{
Log.d(TAG, "Servicio onDestroy...");
sendMessage("ON STOP SERVICE");
Log.d(TAG, "Servicio destruido...");
}
private void sendMessage(String msg) {
Log.d("sender", "Broadcasting message");
Intent intent = new Intent(msg);
// You can also include some extra data.
intent.putExtra("message", msg);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
的AsyncTask:
public class conexion_thread extends AsyncTask <Void, String, Void> {
public conexion_thread(Context context, String serial, String MWpass, String cas, String webk){
// Recibe un textView perteneciente a la UI para pasar datos entre UI y el Thread.
super();
this.context= context;
cambio_status= false;
status="";
ipequipo="";
IPwanCelular= ""; //IP WAN de este equipo
IPlanCelular= ""; //IP WAN de este equipo
IPlanMW= ""; //IP LAN del MW buscado
IPwanMW= ""; //IP WAN del MW buscado
MWenLAN= false; //el MW esta en LAN
MWserial= serial; // Numero de serial del MW.
MWpassword= MWpass; // Password del MW.
casilla= cas; // Casilla de VM telefonico del usuario.
webkey= webk; // Clave web del usuario.
}
@Override
protected Void doInBackground(Void... params){
// Mientras que no se quiera salir de la tarea.
while(estado_conex != EST_CONEX_QUIT){
// Ver si hay que dormir o procesar.
if(sleep_thread > 0){
// Si el tiempo de dormir es mayor que cero se duerme la tarea.
try{
// Pone a dormir el thread.
Thread.sleep(sleep_thread);
// Ver si hay datos/red al terminar de esperar.
if(!isNetworkAvailable(context)){
// Si no hay conexion vuelve a polear hasta que la encuentre.
setStatus("No hay conexion a internet.");
// Pone a dormir 1 segundo.
sleep_thread=1000;
// Cuando se pierde la conexion, debe volver a registrar porque puede cambiar el IP.
estado_conex= EST_CONEX_INIT;
sendMessage(Constants.SIN_CONEXION);
}else{
// Borra el tiempo a dormir ni bien termino de dormir asi procesa.
sleep_thread= 0;
}
}catch(InterruptedException e){
// Error en el sleep.
setStatus("Error interno (001)");
// Interrupt en la tarea, lo mata el OS por otro lado.
// Exit.
break;
}
}else{
// here i do the magic, but the
// Maquina de estados.
switch(estado_conex){
case EST_CONEX_INIT:
// Fijarse de tener todos los datos y conexion a internet.
publishProgress("EST_CONEX_INIT");
if(MWserial.isEmpty() ||
MWpassword.isEmpty() ||
casilla.isEmpty() ||
webkey.isEmpty() ){
// Si hay un campo vacio, no se puede iniciar nada.
setStatus("Faltan datos de conexion.");
// No cambia el estado, va a dormir y reintenta.
sleep_thread= 1000*60*1; //En ms. Son 1 minuto.
}
// Esta todo OK para intentar conectar.
estado_conex= EST_CONEX_GET_RND_DYNIP;
sendMessage(Constants.CONECTANDO_A_MW);
break;
case EST_CONEX_GET_RND_DYNIP:
// 1- Obtener la clave para DynIP
publishProgress("EST_CONEX_GET_RND_DYNIP");
claveDynIP= getClaveDynIP();
if((claveDynIP.isEmpty()) ||
(claveDynIP == "ERROR")){
// Si esta vacia o es ERROR
// Error al obtener el random.
// No cambia el estado, va a dormir y reintenta.
sleep_thread= 1000*60*3; //En ms. Son 3 minutos.
estado_conex= EST_CONEX_INIT;
}else{
// 2- Obtener el IP del equipo y del celular.
ipequipo= getIPs();
if(ipequipo.isEmpty()){
// Si esta vacio es error.
sleep_thread= 1000*60*3; //En ms. Son 3 minutos.
// Pasa a estado inicial para volver a empezar.
estado_conex= EST_CONEX_INIT;
}else{
// OK, pasar al siguiente estado.
estado_conex= EST_CONEX_GET_MW_SERIAL;
sendMessage(Constants.IPS_RESUELTOS, ipequipo);
}
}
break;
case EST_CONEX_GET_MW_SERIAL:
// 3- Obtenes el random/serial del MW para encriptar.
publishProgress("EST_CONEX_GET_MW_SERIAL");
claveMW= obtenerClaveMW(ipequipo);
if(claveMW.isEmpty()){
//Error!
// No cambia el estado, va a dormir y reintenta.
sleep_thread= 1000*60*3; //En ms. Son 3 minutos.
estado_conex= EST_CONEX_GET_RND_DYNIP;
}else{
// OK
estado_conex= EST_CONEX_POLL_MW;
}
break;
case EST_CONEX_POLL_MW:
// 4- Ya tengo todo para polear e indicarle que estoy online.
publishProgress("EST_CONEX_POLL_MW");
if(isClaveMWValid() == false){
// Primero ver si no vencio la clave.
// Si vencio, volver a pedirla.
estado_conex= EST_CONEX_GET_MW_SERIAL;
}
if(polearMW(ipequipo, MWserial, MWpassword, casilla, webkey, 1, 2, claveMW, getIPAddress())){
// Esta conectado. No cambia el estado, polea cada 1min para mantenerse vivo.
sleep_thread= 1000*59*5; //En ms. Son aprox 5 minutos.
sendMessage(Constants.CONECTADO_A_MW, ""+VoiceMailMsgNumber);
}else{
// Error!
sleep_thread= 1000*60*1; //En ms. Es 1 minuto.
// Pasa a obtener serial nuevamente.
estado_conex= EST_CONEX_GET_MW_SERIAL;
}
break;
default:
// Error se corrompio el estado del poleo.
break;
}
}
if(cambio_status){
publishProgress(status);
}
}
if(estado_conex == EST_CONEX_QUIT){
publishProgress("DEBUG: matando tarea.");
}
return null;
}
@Override
protected void onProgressUpdate(String... progress) {
//String aux= t_local.getText() + "\n";
//aux= aux + progress[0];
//t_local.setText(aux);
//t_local.append(progress[0]+"\n");
}
private void sendMessage(String... msgs) {
// Obtiene la cantidad de parametros.
int count = msgs.length;
if(count > 0){
// Crea intent.
Intent intent = new Intent(msgs[0]);
for(int i=1 ; i<count; i++){
intent.putExtra("message_"+count, msgs[i]);
}
/****The app crash here*****/
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
}
希望您能理解我的令人毛骨悚然的代码。
也许你可以仔细检查崩溃是如何发生的。广播系统是一个很好的选择。更确切地说,参见LocalBroadcastManager。
如果你会更具体地解释(也许显示代码)你正在尝试做什么,也许人们可以帮助你。
编辑并添加代码 –
乍一看,我建议你看看[IntentService](https://developer.android.com/training/run-background-service/create-service.html),它可以帮助你摆脱这个AsyncTask。另外,您似乎没有注销您的接收器。关于崩溃,确切的错误是什么? (错误日志将有所帮助) –
我把服务和asynk任务放在intentService中。目前正在努力工作,很快就会再次报告病情。 –
你能提供一些示例代码吗? –
完成! @迈克尔多德 –