简体   繁体   中英

Android app debugging on real device

I am testing my last android app on a real device and it crashes on the second screen.

Tested on the simulator it works fine.

This is the debugging message when it crashes.....

Any help is welcome to find out where to begin to solve the issue.

10-22 21:31:09.364: E/WindowManager(31009): android.view.WindowLeaked: Activity com.solinpromex.casajuventudtrescantos.Cursos_MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{456e0908 V.E..... R......D 0,0-580,163} that was originally added here
10-22 21:31:09.364: E/WindowManager(31009):     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:468)
10-22 21:31:09.364: E/WindowManager(31009):     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:267)
10-22 21:31:09.364: E/WindowManager(31009):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.Dialog.show(Dialog.java:289)
10-22 21:31:09.364: E/WindowManager(31009):     at com.solinpromex.casajuventudtrescantos.Cursos_MainActivity$DownloadJSON.onPreExecute(Cursos_MainActivity.java:77)
10-22 21:31:09.364: E/WindowManager(31009):     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587)
10-22 21:31:09.364: E/WindowManager(31009):     at android.os.AsyncTask.execute(AsyncTask.java:535)
10-22 21:31:09.364: E/WindowManager(31009):     at com.solinpromex.casajuventudtrescantos.Cursos_MainActivity.onResume(Cursos_MainActivity.java:145)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1198)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.Activity.performResume(Activity.java:5538)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3053)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3092)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2463)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.ActivityThread.access$900(ActivityThread.java:172)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1305)
10-22 21:31:09.364: E/WindowManager(31009):     at android.os.Handler.dispatchMessage(Handler.java:102)
10-22 21:31:09.364: E/WindowManager(31009):     at android.os.Looper.loop(Looper.java:146)
10-22 21:31:09.364: E/WindowManager(31009):     at android.app.ActivityThread.main(ActivityThread.java:5598)
10-22 21:31:09.364: E/WindowManager(31009):     at java.lang.reflect.Method.invokeNative(Native Method)
10-22 21:31:09.364: E/WindowManager(31009):     at java.lang.reflect.Method.invoke(Method.java:515)
10-22 21:31:09.364: E/WindowManager(31009):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
10-22 21:31:09.364: E/WindowManager(31009):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
10-22 21:31:09.364: E/WindowManager(31009):     at dalvik.system.NativeStart.main(Native Method)

ACTIVITY CODE ADDED:

package com.solinpromex.casajuventudtrescantos;


import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.os.Build;
import android.app.Activity;

import android.widget.Toast;

public class MainActivity extends Activity implements View.OnTouchListener  {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView iv = (ImageView) findViewById (R.id.image);
        if (iv != null) {
           iv.setOnTouchListener (this);
        }





    }


    public boolean onTouch (View v, MotionEvent ev) 
    {
        boolean handledHere = false;

        final int action = ev.getAction();

        final int evX = (int) ev.getX();
        final int evY = (int) ev.getY();
        int nextImage = -1;         // resource id of the next image to display

        // If we cannot find the imageView, return.
        ImageView imageView = (ImageView) v.findViewById (R.id.image);
        if (imageView == null) return false;

        // When the action is Down, see if we should show the "pressed" image for the default image.
        // We do this when the default image is showing. That condition is detectable by looking at the
        // tag of the view. If it is null or contains the resource number of the default image, display the pressed image.
        Integer tagNum = (Integer) imageView.getTag ();
        int currentResource = (tagNum == null) ? R.drawable.p2_ship_default : tagNum.intValue ();

        // Now that we know the current resource being displayed we can handle the DOWN and UP events.

        switch (action) {
        case MotionEvent.ACTION_DOWN :
           if (currentResource == R.drawable.p2_ship_default) {
            //  nextImage = R.drawable.p2_ship_pressed;
              handledHere = true;
           /*
           } else if (currentResource != R.drawable.p2_ship_default) {
             nextImage = R.drawable.p2_ship_default;
             handledHere = true;
           */
           } else handledHere = true;
           break;

        case MotionEvent.ACTION_UP :
           // On the UP, we do the click action.
           // The hidden image (image_areas) has three different hotspots on it.
           // The colors are red, blue, and yellow.
           // Use image_areas to determine which region the user touched.
           int touchColor = getHotspotColor (R.id.image_areas, evX, evY);

           // Compare the touchColor to the expected values. Switch to a different image, depending on what color was touched.
           // Note that we use a Color Tool object to test whether the observed color is close enough to the real color to
           // count as a match. We do this because colors on the screen do not match the map exactly because of scaling and
           // varying pixel density.
           ColorTool ct = new ColorTool ();
           int tolerance = 25;
          // nextImage = R.drawable.p2_ship_default;


           if (ct.closeMatch (Color.RED, touchColor, tolerance))
           {
               Toast.makeText(getApplicationContext(), 
                       "CASA DE LA JUVENTUD", Toast.LENGTH_LONG).show();
               Intent intent = new Intent(MainActivity.this, categorias_list.class);
            startActivity(intent);
           }

           else if (ct.closeMatch (Color.YELLOW, touchColor, tolerance))
           {
               Toast.makeText(getApplicationContext(), 
                       "ZONAS OFICIALES", Toast.LENGTH_LONG).show();
               Intent intent = new Intent(MainActivity.this, categorias_list.class);
            startActivity(intent);
           }
           else if (ct.closeMatch (Color.rgb(164,199,57) , touchColor, tolerance))
           {
               Toast.makeText(getApplicationContext(), 
                       "ZONAS WI-FI", Toast.LENGTH_LONG).show();
               Intent intent = new Intent(MainActivity.this, categorias_list.class);
            startActivity(intent);
           }
           else if (ct.closeMatch (Color.LTGRAY , touchColor, tolerance))
           {
               Toast.makeText(getApplicationContext(), 
                       "ZONA DEPORTES", Toast.LENGTH_LONG).show();
               Intent intent = new Intent(MainActivity.this, categorias_list.class);
            startActivity(intent);
           }
           else if (ct.closeMatch (Color.BLUE , touchColor, tolerance))
           {
               Toast.makeText(getApplicationContext(), 
                       "ZONA COPAS", Toast.LENGTH_LONG).show();
               Intent intent = new Intent(MainActivity.this, categorias_list.class);
            startActivity(intent);
           }
           else if (ct.closeMatch (Color.WHITE , touchColor, tolerance))
           {
               Toast.makeText(getApplicationContext(), 
                       "ZONA QUEDADAS", Toast.LENGTH_LONG).show();
               Intent intent = new Intent(MainActivity.this, categorias_list.class);
            startActivity(intent);
           }
           else if (ct.closeMatch (Color.BLACK , touchColor, tolerance))
           {
               Toast.makeText(getApplicationContext(), 
                       "ZONA CULTURA", Toast.LENGTH_LONG).show();
               Intent intent = new Intent(MainActivity.this, Cursos_MainActivity.class);
            startActivity(intent);
           }


           // If the next image is the same as the last image, go back to the default.
           // toast ("Current image: " + currentResource + " next: " + nextImage);
           if (currentResource == nextImage) {
              nextImage = R.drawable.p2_ship_default;
           } 
           handledHere = true; 
           break;

        default:
           handledHere = false;

        } // end switch

        if (handledHere) {

           if (nextImage > 0) {
              imageView.setImageResource (nextImage);
              imageView.setTag (nextImage);
           }
        }
        return handledHere;
    } 


    public void openOfertas(View view) 
    {
        Intent intent = new Intent(MainActivity.this, categorias_list.class);
        startActivity(intent);
    }

    public void openArtesania(View view) 
    {
        Intent intent = new Intent(MainActivity.this, Artesania_MainActivity.class);
        startActivity(intent);
    }

    public void openCursos(View view) 
    {
        Intent intent = new Intent(MainActivity.this, Cursos_MainActivity.class);
        startActivity(intent);
    }
    public void openAvisos(View view) 
    {
        Intent intent = new Intent(MainActivity.this, Avisos_MainActivity.class);
        startActivity(intent);
    }

    public void openMapa(View view) 
    {
        Intent intent = new Intent(MainActivity.this, Mapa_MainActivity.class);
        startActivity(intent);
    }





    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    public int getHotspotColor (int hotspotId, int x, int y) {
        ImageView img = (ImageView) findViewById (hotspotId);
        if (img == null) {
           Log.d ("ImageAreasActivity", "Hot spot image not found");
           return 0;
        } else {
          img.setDrawingCacheEnabled(true); 
          Bitmap hotspots = Bitmap.createBitmap(img.getDrawingCache()); 
          if (hotspots == null) {
             Log.d ("ImageAreasActivity", "Hot spot bitmap was not created");
             return 0;
          } else {
            img.setDrawingCacheEnabled(false);
            return hotspots.getPixel(x, y);
          }
        }
    }




}

ADDED ACTIVITY Cursos_MainActivity

package com.solinpromex.casajuventudtrescantos;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;

public class Cursos_MainActivity extends Activity {
    // Declare Variables


    JSONObject jsonobject;
    JSONArray jsonarray;
    ListView listview;
    Cursos_ListViewAdapter adapter;
    ProgressDialog mProgressDialog;
    ArrayList<HashMap<String, String>> arraylist;

    static String VALORACIONARTESANO = "valoracionArtesano";
    static String NOMBREARTESANO = "nombreArtesano";
    static String DIRECCIONARTESANO = "direccionArtesano";
    static String LOGOARTESANO = "logoArtesano";
    static String TELEFONOARTESANO = "telefonoArtesano";
    static String FACEBOOKARTESANO = "facebookArtesano";
    static String EMAILARTESANO = "emailArtesano";
    static String TEXTARTESANO = "textArtesano";
    static String LATITUD = "latitud";
    static String LONGITUD = "longitud";
    static String IDARTESANO = "idArtesano";
    static String CIUDAD = "ciudad";
    static String CP = "cp";
    static String WEB = "web";



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.v("MVASCO", "context is null!");
         // getting intent data
        Intent in = getIntent();
     // JSON node keys



        this.setTitle("Zona Cultura");
        // Get the view from listview_main.xml
        setContentView(R.layout.cursos_listview_main);
        // Execute DownloadJSON AsyncTask
        //new DownloadJSON().execute();
    }

    // DownloadJSON AsyncTask
    private class DownloadJSON extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Create a progressdialog
            mProgressDialog = new ProgressDialog(Cursos_MainActivity.this);
            // Set progressdialog title
            mProgressDialog.setTitle("Casa de la Juventud");
            // Set progressdialog message
            mProgressDialog.setMessage("Zona Cultura");
            mProgressDialog.setIndeterminate(false);
            // Show progressdialog
            mProgressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // Create an array
            arraylist = new ArrayList<HashMap<String, String>>();
            // Retrieve JSON Objects from the given URL address
            jsonobject = JSONfunctions
                    .getJSONfromURL("http://www.solinpromex.com/casajuventud/android/android_centros.php");

            try {
                // Locate the array name in JSON
                jsonarray = jsonobject.getJSONArray("Categorias");

                for (int i = 0; i < jsonarray.length(); i++) {
                    HashMap<String, String> map = new HashMap<String, String>();
                    jsonobject = jsonarray.getJSONObject(i);
                    // Retrive JSON Objects
                    String codpostal = jsonobject.getString("cp_zonacultura");
                    map.put("valoracionArtesano", jsonobject.getString("valoracion_zonacultura"));
                    map.put("nombreArtesano", jsonobject.getString("nombre_zonacultura"));
                    map.put("direccionArtesano", jsonobject.getString("direccion_zonacultura"));
                    map.put("logoArtesano", jsonobject.getString("imagen_zonacultura"));
                    map.put("telefonoArtesano", jsonobject.getString("tel_zonacultura"));
                    map.put("emailArtesano", jsonobject.getString("email_zonacultura"));
                    map.put("textArtesano", jsonobject.getString("desc_zonacultura"));
                    map.put("facebookArtesano", jsonobject.getString("facebook_zonacultura"));
                    map.put("latitud", jsonobject.getString("latitud_zonacultura"));
                    map.put("longitud", jsonobject.getString("longitud_zonacultura"));
                    map.put("idArtesano", jsonobject.getString("id_zonacultura"));
                    map.put("ciudad", codpostal+" "+jsonobject.getString("ciudad_zonacultura"));
                    map.put("cp", jsonobject.getString("cp_zonacultura"));
                    map.put("web", jsonobject.getString("web_zonacultura"));




Log.d("NOMBRE DEL SITIO ", "Value: " + (jsonobject.getString("nombre_zonacultura")));

                    // Set the JSON Objects into the array
                    arraylist.add(map);
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            // Locate the listview in listview_main.xml
            listview = (ListView) findViewById(R.id.listview);
            // Pass the results into ListViewAdapter.java
            adapter = new Cursos_ListViewAdapter(Cursos_MainActivity.this, arraylist);
            // Set the adapter to the ListView
            listview.setAdapter(adapter);

            // Close the progressdialog
            mProgressDialog.dismiss();
        }
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        new DownloadJSON().execute();
    }

}

your mProgressDialog is leaking memory.

try this

mProgressDialog = new ProgressDialog(this.getApplicationContext());

I think that the problem is in :

adapter = new Cursos_ListViewAdapter(Cursos_MainActivity.this, arraylist);
        // Set the adapter to the ListView
        listview.setAdapter(adapter);

I have no idea what is in your adapter but usual you are dealing there with views.

Don't forget that "onPostExecute" is still in the other Thread and you are trying to work with the views from the main thread/activity ...

The best solution for things like that is to pass to the AsyncTask some Interface and when is done the AsyncTask will pass the data back to the activity.

This is also much more close to SOLID . The AsyncTask shall get the data and pass it over. The adapter shall shown the received data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM