【问题标题】:android debugging ddms vs eclipse debugger / code not working on android 4.0android调试ddms vs eclipse调试器/代码在android 4.0上不起作用
【发布时间】:2012-01-04 21:49:51
【问题描述】:

一直试图弄清楚为什么我的代码现在几天都无法在新的 4.0 模拟器中运行并且似乎无法深入了解它,我在 2.2 sdk 中运行良好的代码在4.0 sdk 模拟器,因此我一直在尝试追踪一些有关调试的教程,但似乎无法清楚地解释哪一个是最好的,或者坦率地说是如何执行这些功能的清晰方法,所以我的问题是哪个最好,最好的方法是什么?

更新:

例外:

11-23 10:16:34.655: E/AndroidRuntime(1358): java.lang.RuntimeException:
        Unable to resume activity {com.testapp2.second/com.testapp2.second.activities.AuthorizationActivity}: android.os.NetworkOnMainThreadException
11-23 10:16:34.655: E/AndroidRuntime(1358): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2443)

这是我的代码: 活动1:

package com.testapp2.second.activities;

import com.testapp2.second.OTweetApplication;
import com.testapp2.second.R;

import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;

public class Testapp2Activity extends ListActivity {

private Twitter twitter;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = (OTweetApplication)getApplication();
twitter = app.getTwitter();

setContentView(R.layout.main);
}

@Override
protected void onResume() {
super.onResume();
if (!app.isAuthorized()) {
  beginAuthorization();
} else {
  loadTimelineIfNotLoaded();
}
}

private void loadTimelineIfNotLoaded() {
loadHomeTimeline();
}

private void beginAuthorization() {
Intent intent = new Intent(this, AuthorizationActivity.class);
startActivity(intent);
}

private void loadHomeTimeline() {
try {
  ResponseList<Status> statii = twitter.getHomeTimeline();
  StatusListAdapter adapter = new StatusListAdapter(this, statii);
  setListAdapter(adapter);
} catch (TwitterException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}
}

private class StatusListAdapter extends ArrayAdapter<Status> {

public StatusListAdapter(Context context, ResponseList<Status> statii) {
  super(context, android.R.layout.simple_list_item_1, statii);
}

}
}

活动 2:

package com.testapp2.second.activities;

import com.testapp2.second.OTweetApplication;
import com.testapp2.second.R;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class AuthorizationActivity extends Activity {

private OTweetApplication app;
private WebView webView;

private WebViewClient webViewClient = new WebViewClient() {
@Override
public void onLoadResource(WebView view, String url) {
  // the URL we're looking for looks like this:
  // http://otweet.com/authenticated?oauth_token=1234567890qwertyuiop
  Uri uri = Uri.parse(url);
  if (uri.getHost().equals("otweet.com")) {
    String token = uri.getQueryParameter("oauth_token");
    if (null != token) {
      webView.setVisibility(View.INVISIBLE);
      app.authorized();
      finish();
    } else {
      // tell user to try again 
    }
  } else {
    super.onLoadResource(view, url);
  }
 }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = (OTweetApplication)getApplication();
setContentView(R.layout.authorization_view);
setUpViews();
}

@Override
protected void onResume() {
super.onResume();
String authURL = app.beginAuthorization();
webView.loadUrl(authURL);
}

private void setUpViews() {
webView = (WebView)findViewById(R.id.web_view);
webView.setWebViewClient(webViewClient);
}

}

扩展应用:

package com.testapp2.second;

import com.testapp2.second.authorization.OAuthHelper;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import android.app.Application;

public class OTweetApplication extends Application {

private Twitter twitter;
private RequestToken currentRequestToken;
private OAuthHelper oAuthHelper;

@Override
public void onCreate() {
super.onCreate();
oAuthHelper = new OAuthHelper(this);
twitter = new TwitterFactory().getInstance();
oAuthHelper.configureOAuth(twitter);
}

public Twitter getTwitter() {
return twitter;
}

public boolean isAuthorized() {
return oAuthHelper.hasAccessToken();
}

public String beginAuthorization() {
try {
  if (null == currentRequestToken) {
    currentRequestToken = twitter.getOAuthRequestToken();
  }
  return currentRequestToken.getAuthorizationURL();
} catch (TwitterException e) {
  e.printStackTrace();
}
return null;
}

public boolean authorize(String pin) {
try {
  AccessToken accessToken = twitter.getOAuthAccessToken(currentRequestToken, pin);
  oAuthHelper.storeAccessToken(accessToken);
  return true;
} catch (TwitterException e) {
  throw new RuntimeException("Unable to authorize user", e); 
}
}

public void authorized() {
try {
  AccessToken accessToken = twitter.getOAuthAccessToken();
  oAuthHelper.storeAccessToken(accessToken);
} catch (TwitterException e) {
  throw new RuntimeException("Unable to authorize user", e); 
}

}

}

oauth 助手:

package com.testapp2.second.authorization;

import java.io.InputStream;
import java.util.Properties;

import com.testapp2.second.R;

import twitter4j.Twitter;
import twitter4j.auth.AccessToken;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class OAuthHelper {

private static final String APPLICATION_PREFERENCES = "app_prefs";
private static final String AUTH_KEY = "auth_key";
private static final String AUTH_SEKRET_KEY = "auth_secret_key";
private SharedPreferences prefs;
private AccessToken accessToken;
private String consumerSecretKey;
private String consumerKey;
private Context context;

public OAuthHelper(Context context) {
this.context = context;
prefs = context.getSharedPreferences(APPLICATION_PREFERENCES, Context.MODE_PRIVATE);
loadConsumerKeys();
accessToken = loadAccessToken();
}

public void configureOAuth(Twitter twitter) {
twitter.setOAuthConsumer(consumerKey, consumerSecretKey);
twitter.setOAuthAccessToken(accessToken);
}

public boolean hasAccessToken() {
return null != accessToken;
}

public void storeAccessToken(AccessToken accessToken) {
Editor editor = prefs.edit();
editor.putString(AUTH_KEY, accessToken.getToken());
editor.putString(AUTH_SEKRET_KEY, accessToken.getTokenSecret());
editor.commit();
this.accessToken = accessToken;
}

private AccessToken loadAccessToken() {
String token = prefs.getString(AUTH_KEY, null);
String tokenSecret = prefs.getString(AUTH_SEKRET_KEY, null);
if (null != token && null != tokenSecret) {
  return new AccessToken(token, tokenSecret);
} else {
  return null;
}
}

private void loadConsumerKeys() {
try {
  Properties props = new Properties();
  InputStream stream = context.getResources().openRawResource(R.raw.oauth);
  props.load(stream);
  consumerKey = (String)props.get("consumer_key");
  consumerSecretKey = (String)props.get("consumer_secret_key");
} catch (Exception e) {
  throw new RuntimeException("Unable to load consumer keys from oauth.properties", e);
}
}
}

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.testapp2.second"
android:versionCode="1"
android:versionName="1.0" >

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Light"
    android:name=".OTweetApplication" >
    <activity
        android:label="@string/app_name"
        android:name=".activities.Testapp2Activity" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".activities.AuthorizationActivity"      android:label="@string/authorization" />
</application>
<uses-sdk android:minSdkVersion="14" />

<uses-permission android:name="android.permission.INTERNET" />

</manifest>

【问题讨论】:

  • 对于您的问题,我只想查看 LogCat 中的“错误”部分并将结果发布在这里,我们可以为您指明正确的方向
  • 这里是 logcat 向我显示的前 2 个错误:11-23 10:16:34.655: E/AndroidRuntime(1358): java.lang.RuntimeException: Unable to resume activity {com. testapp2.second/com.testapp2.second.activities.AuthorizationActivity}:android.os.NetworkOnMainThreadException 和:11-23 10:16:34.655:E/AndroidRuntime(1358):在 android.app.ActivityThread.performResumeActivity(ActivityThread.java :2443)
  • 请将代码/例外添加到您的帖子中,而不是作为评论

标签: android eclipse debugging android-emulator ddms


【解决方案1】:

Imo ddms,在那里你可以看到 logcat,它会告诉你所有你需要知道的关于你的应用发生了什么。我不确定 r15,主要是因为我一直在使用设备进行调试,但在旧版本上,模拟器无法获取所有异常,使得调试阶段很痛苦

【讨论】:

    【解决方案2】:

    DDMS 不是源代码调试器,它提供:

    • 端口转发服务
    • 设备上的屏幕截图
    • 设备上的线程和堆信息
    • logcat、进程和无线电状态信息
    • 来电和短信欺骗
    • 位置数据欺骗

    另一方面,使用 Eclipse,您可以在代码中设置断点。

    【讨论】:

      【解决方案3】:

      第一个例外说明一切:NetworkOnMainThreadException

      你永远不应该在 UI 线程上做网络事情。您应该在 Thread/AsyncTask 中执行此操作。

      如果您向我们提供您的活动代码,我们可以告诉您应该更改的内容。

      更新:

      在您的onResume()AuthorizationActivity 中,您调用app.beginAuthorization();,它可以调用twitter.getOAuthRequestToken(),据我在twitter4j api 中看到的,它建立网络连接。所以这不应该在运行在 UI 线程/主线程中的onResume() 中完成。

      我的建议:在AsyncTask 中进行 twitter 通信/身份验证,因为您永远不知道连接的速度可能有多快/多慢。您应该在连接速度较慢的情况下测试您当前的应用程序。我猜您的应用程序和/或application not responding 消息可能会响应缓慢。

      阅读本文以获取更多信息:Designing for Responsiveness

      它在 4.0 以下工作的原因是:它是在 API 11 中引入的:NetworkOnMainThreadException

      【讨论】:

      • 我有大约 4 个活动/课程以及清单,将在上面发布。
      • @EdmundRojas 请先发布AuthorizationActivity 的代码。比你应该明白...
      • 抱歉耽搁了,我终于可以发布活动了,很抱歉错过了这个关于授权活动的消息。
      • 还有很多我在更高版本的代码中使用异步任务处理的网络任务这只是一个基本的身份验证示例,以确保一切正常,不管它在 2.1 和 2.2 中起作用的奇怪原因但不会在 4.0 中工作。
      猜你喜欢
      • 2012-05-24
      • 2011-06-04
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 2019-06-11
      • 1970-01-01
      相关资源
      最近更新 更多