[英]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.