繁体   English   中英

在真实设备上调试Android应用

[英]Android app debugging on real device

我正在真实设备上测试我的最后一个android应用程序,它在第二个屏幕上崩溃。

在模拟器上测试它可以正常工作。

这是当它崩溃时的调试消息。

欢迎任何帮助以找出从哪里开始解决问题的方法。

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)

添加的活动代码:

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);
          }
        }
    }




}

增加的活动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();
    }

}

您的mProgressDialog正在泄漏内存。

尝试这个

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

我认为问题出在:

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

我不知道您的适配器中有什么,但是通常您正在那里处理视图。

不要忘记“ onPostExecute”仍然在另一个线程中,并且您正在尝试使用主线程/活动中的视图...

最好的解决方案是将某些接口传递给AsyncTask,完成后AsyncTask会将数据传递回活动。

这也更接近SOLID AsyncTask应获取数据并将其传递。 适配器应显示收到的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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