Autore Topic: Eccezione su AsyncTask ritardato  (Letto 549 volte)

Offline gius83

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Eccezione su AsyncTask ritardato
« il: 22 Maggio 2015, 11:46:11 CEST »
0
Buongiorno a tutti,
sono un nuovo e mi appresto ad entrare nel mondo dello sviluppo Android per la prima volta e ho qualche difficoltà.
Una cosa particolarmente ostica che ho trovato è il sistema di debug di Eclipse, in particolare LogCat, dove non si riesce a capire che tipo di errore mi da l'applicazione.

Ad ogni modo come primo progetto ho creato una applicazione che per il momento esegue questi semplici compiti:
- All'avvio l'activity principale mostra la sua view
- Dopodichè avvia un AsyncTask ritardato che fa il check del bluetooth
- Quest'ultimo verifica se il bluetooth è supportato dal telefono se non fa chiudere l'applicazione inviando un messaggio all'Activity chiamante, viceversa chiede il permesso per attivare il Bluetooth

Il sistema è così congeniato:

Ci sono due classi su due file .java. La classe principale su un file e la classe con i metodi che si occupa di gestire operazioni sul Bluetooth.
L'activity principale:
- crea l'oggetto dalla classe del bluetooth
- crea un manipolatore dei messaggi mHandler utilizzato per lo scambio dei messaggi fra l'activity principale e il task asincrono
- crea un manipolatore del ritardo dHandler
- dopodiche su onCreate tramite il metodo postDelayed avvia il task asincrono definito nella classe bluetooth passandogli il contesto e il manipolatore dei messaggi

Quindi in teoria dopo 2000 ms il task asincrono definito nella classe della libreria bluetooth dovrebbe essere avviato. Questo task fa il test se il bluetooth è supportato e se è acceso oppure spento. Chiede conferma di accenderlo se è spento, e restituisce un messaggio all'activity chiamante.
Il task dovendo chiedere all'utente l'autorizzazione se accendere o meno il bluetooth, sono stato costretto a dichiarare la classe principale della libreria bluetooth come estensione di activity perchè mi pare di capire che solo così può andare a modificare la view del contesto attuale.

Ad ogni modo quando avvio l'app mi da errore e mi dice che il problema è causato dal metodo .postDelayed ma senza dirmi perchè. Forse potete aiutarmi. Vi posto il codice delle classi e il logCat:
Codice (Java): [Seleziona]
package com.example.myproject;

import com.example.myproject.R;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

public class Mainclass extends Activity{

        private Handler dHandler; //manipolatore ritardo       
        public final BLElib BLEclass = new BLElib();

       
       
        //manipolatore messaggi in ingresso
        final Handler mHandler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                Bundle b;
               
                if(msg.what==BLEclass.BTCODE){
         
                    b=msg.getData();
         
                    if(b.getString("result").equals("not_supported")){
                                    Toast.makeText(Mainclass.this, R.string.ble_not_supported, Toast.LENGTH_LONG).show();
                                   
                                        dHandler.postDelayed(
                                                        new Runnable() {                                                               
                                                                @Override
                                                                public void run() {
                                                                        chiudiApp();
                                                                }
                                                        }
                                                        , 1000);
                                   
                    }
                    if(b.getString("result").equals("enabled")){
                       
                    }
                    if(b.getString("result").equals("exit")){
                        chiudiApp();
                    }
         
                }              
              }
        };
       
       
        //first start
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.splash);
               
                if(savedInstanceState == null){ //app just started
                       
                        dHandler.postDelayed(
                                        new Runnable() {                                               
                                                @Override
                                                public void run() {
                                                        BLEclass.new StartBluetooth(getApplicationContext(),mHandler).execute();
                                                }
                                        }
                                        , 2000);
                       
                       
                       
                }else{ //app started last
                       
                }
        }
       
        @Override
        public void onPause()
        {
                super.onPause();
        }
       
        @Override
        public void onDestroy()
        {
                super.onDestroy();             
        }
       
       
        public void chiudiApp(){
                finish();
        }
       
       
}
Codice (Java): [Seleziona]
package com.example.myproject;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;

public class BLElib extends Activity{
        public final int BTCODE = 2000; //codice messaggi classe
        private StringBuffer result = new StringBuffer();
       
       
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode==BTCODE && resultCode==RESULT_OK)
            {
                result = new StringBuffer("enabled");
            }else
                result = new StringBuffer("exit");
        }
       
       
        public class StartBluetooth extends AsyncTask<Void, Void, String>
        {
                private Context context;
                private BluetoothAdapter btAdapter;
                private Handler hd;
               
                               
                public StartBluetooth(Context pContext, Handler pHd){
                        this.context=pContext;
                        this.hd=pHd;
                }
                               
                protected String doInBackground(Void... argomenti){
                        // Use this check to determine whether BLE is supported on the device.
                       
                        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {                                                                     
                            result = new StringBuffer("not_support");
                        }else{
                                btAdapter = BluetoothAdapter.getDefaultAdapter();
                                result = new StringBuffer("exit");
                                if (!btAdapter.isEnabled()){
                                        Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                        startActivityForResult(turnOn, BTCODE);                                        
                                }else result = new StringBuffer("enabled");
                        }
                       
                                               
                        return "fine";
                }
               
                @Override
                protected void onPreExecute(){
                }
               
                @Override
                protected void onProgressUpdate(Void...valori){
                }
               
                @Override
                protected void onPostExecute(String risultato){                
                        Bundle b = new Bundle();
                        Message msg = hd.obtainMessage();
                        msg.what=BTCODE;
                        b.putString("result", result.toString());
                        msg.setData(b);
                        hd.sendMessage(msg);
                }
               

        }
}
Codice (XML): [Seleziona]
05-22 09:31:55.594: W/ActivityThread(601): Application com.example.myproject is waiting for the debugger on port 8100...
05-22 09:31:55.604: I/System.out(601): Sending WAIT chunk
05-22 09:31:55.614: I/dalvikvm(601): Debugger is active
05-22 09:31:55.813: I/System.out(601): Debugger has connected
05-22 09:31:55.813: I/System.out(601): waiting for debugger to settle...
05-22 09:31:56.014: I/System.out(601): waiting for debugger to settle...
05-22 09:31:56.214: I/System.out(601): waiting for debugger to settle...
05-22 09:31:56.414: I/System.out(601): waiting for debugger to settle...
05-22 09:31:56.614: I/System.out(601): waiting for debugger to settle...
05-22 09:31:56.814: I/System.out(601): waiting for debugger to settle...
05-22 09:31:57.024: I/System.out(601): waiting for debugger to settle...
05-22 09:31:57.224: I/System.out(601): waiting for debugger to settle...
05-22 09:31:57.424: I/System.out(601): debugger has settled (1375)
05-22 09:31:57.834: D/dalvikvm(601): GC_EXTERNAL_ALLOC freed 47K, 53% free 2551K/5379K, external 1625K/2137K, paused 45ms
05-22 09:31:58.466: D/dalvikvm(601): threadid=1: still suspended after undo (sc=1 dc=1)
05-22 09:32:05.696: D/AndroidRuntime(601): Shutting down VM
05-22 09:32:05.696: W/dalvikvm(601): threadid=1: thread exiting with uncaught exception (group=0x40015560)
05-22 09:32:05.763: E/AndroidRuntime(601): FATAL EXCEPTION: main
05-22 09:32:05.763: E/AndroidRuntime(601): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myproject/com.example.myproject.Mainclass}: java.lang.NullPointerException
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.app.ActivityThread.access$1500(ActivityThread.java:117)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.os.Handler.dispatchMessage(Handler.java:99)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.os.Looper.loop(Looper.java:123)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.app.ActivityThread.main(ActivityThread.java:3683)
05-22 09:32:05.763: E/AndroidRuntime(601):      at java.lang.reflect.Method.invokeNative(Native Method)
05-22 09:32:05.763: E/AndroidRuntime(601):      at java.lang.reflect.Method.invoke(Method.java:507)
05-22 09:32:05.763: E/AndroidRuntime(601):      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-22 09:32:05.763: E/AndroidRuntime(601):      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-22 09:32:05.763: E/AndroidRuntime(601):      at dalvik.system.NativeStart.main(Native Method)
05-22 09:32:05.763: E/AndroidRuntime(601): Caused by: java.lang.NullPointerException
05-22 09:32:05.763: E/AndroidRuntime(601):      at com.example.myproject.Mainclass.onCreate(Mainclass.java:63)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-22 09:32:05.763: E/AndroidRuntime(601):      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
05-22 09:32:05.763: E/AndroidRuntime(601):      ... 11 more

Post unito: 22 Maggio 2015, 11:53:35 CEST
Quindi da errore su Mainclass.java linea 63 cioè questa:

dHandler.postDelayed(
« Ultima modifica: 22 Maggio 2015, 11:53:35 CEST da gius83, Reason: Merged DoublePost »

Offline LinkOut

  • Utente normale
  • ***
  • Post: 272
  • Respect: +38
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Eccezione su AsyncTask ritardato
« Risposta #1 il: 22 Maggio 2015, 11:54:09 CEST »
+1
Ciao,

tipo di errore: java.lang.RuntimeException:
descrizione errore: Unable to start activity ComponentInfo{com.example.myproject/com.example.myproject.Mainclass}: java.lang.NullPointerException

Chiave:

Caused by: java.lang.NullPointerException
at com.example.myproject.Mainclass.onCreate(Mainclass.java:63)

alla riga 63:
Codice (Java): [Seleziona]
dHandler.postDelayed( 

Però dHandler non è istanziato...quindi è null.

Esempio:
Codice (Java): [Seleziona]
new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
            // Esegui cosa vuoi
            }
        }, 3000L); //Tempo

Offline gius83

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Eccezione su AsyncTask ritardato
« Risposta #2 il: 22 Maggio 2015, 12:30:25 CEST »
0
Si questo problema è risolto.
Grazie dell'aiuto  :-)

Quindi nullpointerexception significa che c'è un componente non istanziato (null) che viene avviato. Ok.

Offline gius83

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Eccezione su AsyncTask ritardato
« Risposta #3 il: 27 Maggio 2015, 18:39:25 CEST »
0
Adesso mi da questo errore:
Codice: [Seleziona]
05-27 18:26:27.581: W/dalvikvm(21883): threadid=13: thread exiting with uncaught exception (group=0x41c93c08)
05-27 18:26:27.586: E/AndroidRuntime(21883): FATAL EXCEPTION: AsyncTask #1
05-27 18:26:27.586: E/AndroidRuntime(21883): Process: com.example.myproject, PID: 21883
05-27 18:26:27.586: E/AndroidRuntime(21883): java.lang.RuntimeException: An error occured while executing doInBackground()
05-27 18:26:27.586: E/AndroidRuntime(21883):         at android.os.AsyncTask$3.done(AsyncTask.java:300)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at java.util.concurrent.FutureTask.run(FutureTask.java:242)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at java.lang.Thread.run(Thread.java:841)
05-27 18:26:27.586: E/AndroidRuntime(21883): Caused by: java.lang.NullPointerException
05-27 18:26:27.586: E/AndroidRuntime(21883):         at android.app.Activity.startActivityForResult(Activity.java:3532)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at android.app.Activity.startActivityForResult(Activity.java:3493)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at com.example.myproject.BLElib$StartBluetooth.doInBackground(BLElib.java:53)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at com.example.myproject.BLElib$StartBluetooth.doInBackground(BLElib.java:1)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-27 18:26:27.586: E/AndroidRuntime(21883):         at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-27 18:26:27.586: E/AndroidRuntime(21883):         ... 4 more
Praticamente me lo da qui:
Codice: [Seleziona]
startActivityForResult(turnOn, BTCODE);        quando avvia una activity di sistema dal task asincrono definito nella classe diversa dalla mainclass.
Trattasi di NullPointerException presumo che il motivo sia che non trova il metodo onActivityResult anche se definito all'interno della classe. Questo perchè in realtà BLElib anche se estende activity non viene in realtà avviata. O sbaglio?
Se avvio l'activity di sistema dalla mainclass definendo onActivityResult funziona. Ma il mio scopo sarebbe quello di gestire il bluetooth mediante task asincroni in un file a parte ma così facendo ho comunque bisogno all'occorrenza di utilizzare toast e notifiche a video come questa che chiede l'autorizzazione ad attivare il bluetooth.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Eccezione su AsyncTask ritardato
« Risposta #4 il: 27 Maggio 2015, 18:50:17 CEST »
0
Non ha senso far partire una activity da un thread parallelo alla tua attuale activity.

Puoi lanciare un'altra activity solo dalla tua attuale activity, o più in dettaglio solo dal thread di UI. Potresti far concludere l'asynctask e nella funzione di chiusura lanciare la nuov activity, oppure mandare un messaggio all'handler della tua attuale activity e poi lasciare che sia quella a lanciarla. Però attenzione, quando cambi activity il tuo asynctask perde la validità del context e diventa orfano (non sa qual'è la nuova activity attiva).
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline gius83

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
Re:Eccezione su AsyncTask ritardato
« Risposta #5 il: 27 Maggio 2015, 19:59:19 CEST »
0
Ho capito.
Grazie della spiegazione.
Se le cose stanno così allora gestirò tutto con gli handler.

Post unito: 28 Maggio 2015, 16:59:43 CEST
Ora va usando gli handler.
Tuttavia non riesco a capire perchè il task asincrono rimane in esecuzione. Lo vedo dal debug che è in esecuzione.
L'handler dei messaggi riceve correttamente la risposta quindi onPostExecute viene eseguito. Pensavo che il task terminasse sul return di doInBackground.
Forse il problema è il comando Runnable che avvia un thread che a sua volta avvia il task asincrono? Runnable non ha un comando di arresto.
Codice (Java): [Seleziona]
package com.example.myproject;

import com.example.myproject.R;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

public class Mainclass extends Activity{

        private Handler dHandler = new Handler(); //manipolatore ritardo       
        public BLElib BLEclass = new BLElib();
       
       
        //manipolatore messaggi in ingresso
        final Handler mHandler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                Bundle b;
               
                if(msg.what==BLEclass.BTCODE){
         
                    b=msg.getData();
         
                    if(b.getString("result").equals("not_support")){
                                    Toast.makeText(Mainclass.this, R.string.ble_not_supported, Toast.LENGTH_LONG).show();
                                   
                                        dHandler.postDelayed(
                                                        new Runnable() {                                                               
                                                                @Override
                                                                public void run() {
                                                                        chiudiApp();
                                                                }
                                                        }
                                                        , 3000);
                                   
                    }
                    if(b.getString("result").equals("disabled")){
                        Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                        startActivityForResult(turnOn, BLEclass.BTCODE);
                    }
                    if(b.getString("result").equals("enabled")){
                        Intent device_list = new Intent(getApplicationContext(),Device_list.class);
                        startActivity(device_list);
                       
                    }
                    if(b.getString("result").equals("exit")){
                        chiudiApp();
                    }
         
                }              
              }
        };
       
       
        //first start
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.splash);
                       
               
                dHandler.postDelayed(
                                new Runnable() {                                               
                                        @Override
                                        public void run() {
                                                BLEclass.new StartBluetooth(getApplicationContext(),mHandler).execute();
                                        }
                                }
                                , 2000);
       
        }
       
        @Override
        public void onPause()
        {
                super.onPause();
        }
       
        @Override
        public void onDestroy()
        {
                super.onDestroy();             
        }
       
       
        public void chiudiApp(){
                finish();
        }
       
       
       
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode==BLEclass.BTCODE && resultCode==RESULT_OK)
            {
                Intent device_list = new Intent(getApplicationContext(),Device_list.class);
                startActivity(device_list);
            }else
                chiudiApp();
        }
       
}
Codice (Java): [Seleziona]
package com.example.myproject;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;

public class BLElib{
        public final int BTCODE = 2000; //codice messaggi classe
        private StringBuffer result = new StringBuffer();
       
       

       
       
        public class StartBluetooth extends AsyncTask<Void, Void, String>
        {
                private Context context;
                private BluetoothAdapter btAdapter;
                private Handler hd;
               
                               
                public StartBluetooth(Context pContext, Handler pHd){
                        this.context=pContext;
                        this.hd=pHd;
                }
                               
                protected String doInBackground(Void... argomenti){
                        // Use this check to determine whether BLE is supported on the device.
                       
                        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {                                                                          
                            result = new StringBuffer("not_support");
                        }else{
                                btAdapter = BluetoothAdapter.getDefaultAdapter();                              
                                if (!btAdapter.isEnabled())
                                        result = new StringBuffer("disabled");                                                                 
                                else
                                        result = new StringBuffer("enabled");
                        }
                                               
                        return "fine";
                }
               

               
                @Override
                protected void onPreExecute(){
                }
               
                @Override
                protected void onProgressUpdate(Void...valori){
                }
               
                @Override
                protected void onPostExecute(String risultato){                
                        Bundle b = new Bundle();
                        Message msg = hd.obtainMessage();
                        msg.what=BTCODE;
                        b.putString("result", result.toString());
                        msg.setData(b);
                        hd.sendMessage(msg);
                }
        }
       
       
       
}
« Ultima modifica: 28 Maggio 2015, 16:59:43 CEST da gius83, Reason: Merged DoublePost »