我正在做一个关于包含推文的 ListView 的教程。它有效,但现在每次都崩溃。我检查了我的代码,它与教程中的完全相同。
public class MainActivity extends Activity {
Button mBtnDownload;
EditText mEtxtUsername;
ProgressDialog mProgressDialog;
TextView mTxtvUserNameTitle;
TextView mTxtvUserName;
TextView mTxtvUrlTitle;
TextView mTxtvUrl;
TextView mTxtvFavouritesCountTitle;
TextView mTxtvFavouritesCount;
TextView mTxtvDescriptionTitle;
TextView mTxtvDescription;
Button mBtnTweets;
TwitterUser mTwitterUser;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nicelayout);
mBtnDownload = (Button) findViewById(R.id.btnDownload);
mEtxtUsername = (EditText) findViewById(R.id.etxtUsername);
mTxtvUserNameTitle = (TextView) findViewById(R.id.txtvUserNameTitle);
mTxtvUserName = (TextView) findViewById(R.id.txtvUserName);
mTxtvUrlTitle = (TextView) findViewById(R.id.txtvUrlTitle);
mTxtvUrl = (TextView) findViewById(R.id.txtvUrl);
mTxtvFavouritesCountTitle = (TextView) findViewById(R.id.txtvFavouritesCountTitle);
mTxtvFavouritesCount = (TextView) findViewById(R.id.txtvFavouritesCount);
mTxtvDescriptionTitle = (TextView) findViewById(R.id.txtvDescriptionTitle);
mTxtvDescription = (TextView) findViewById(R.id.txtvDescription);
mBtnTweets = (Button) findViewById(R.id.btnTweets);
updateView();
}
public void downloadUserInfo(View view){
if (view == mBtnDownload){
String username = mEtxtUsername.getText().toString();
if (username.length() > 0){
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Bezig met het ophalen van gegevens...");
mProgressDialog.show();
new DownloadUserInfoTask().execute();
}
else{
Toast.makeText(this, "Voer een twitter gebruikersnaam in", Toast.LENGTH_LONG).show();
}
}
}
public void showTweets(View view){
if (view == mBtnTweets){
Intent intent = new Intent(this, TweetsActivity.class);
intent.putExtra("twitter_user_name", mTwitterUser.getUserName());
startActivity(intent);
}
}
private DefaultHttpClient createHttpClient() {
HttpParams my_httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(my_httpParams, 3000);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
ThreadSafeClientConnManager multiThreadedConnectionManager = new ThreadSafeClientConnManager(my_httpParams, registry);
DefaultHttpClient httpclient = new DefaultHttpClient(multiThreadedConnectionManager, my_httpParams);
return httpclient;
}
private void updateView(){
if (mTwitterUser == null){
mTxtvUrlTitle.setVisibility(View.INVISIBLE);
mTxtvUrl.setVisibility(View.INVISIBLE);
mTxtvUserNameTitle.setVisibility(View.INVISIBLE);
mTxtvUserName.setVisibility(View.INVISIBLE);
mTxtvFavouritesCountTitle.setVisibility(View.INVISIBLE);
mTxtvFavouritesCount.setVisibility(View.INVISIBLE);
mTxtvDescriptionTitle.setVisibility(View.INVISIBLE);
mTxtvDescription.setVisibility(View.INVISIBLE);
mBtnTweets.setVisibility(View.INVISIBLE);
}
else {
mTxtvUrlTitle.setVisibility(View.VISIBLE);
mTxtvUrl.setVisibility(View.VISIBLE);
mTxtvUserNameTitle.setVisibility(View.VISIBLE);
mTxtvUserName.setVisibility(View.VISIBLE);
mTxtvFavouritesCountTitle.setVisibility(View.VISIBLE);
mTxtvFavouritesCount.setVisibility(View.VISIBLE);
mTxtvDescriptionTitle.setVisibility(View.VISIBLE);
mTxtvDescription.setVisibility(View.VISIBLE);
mBtnTweets.setVisibility(View.VISIBLE);
mTxtvUrl.setText(mTwitterUser.getWebsite());
mTxtvUserName.setText(mTwitterUser.getUserName());
mTxtvFavouritesCount.setText(mTwitterUser.getFavouritesCount() + "");
mTxtvDescription.setText(mTwitterUser.getDescription());
}
}
private class DownloadUserInfoTask extends AsyncTask<Void, Void, Void> {
int mStatusCode = 0;
String mResultString;
Exception mConnectionException;
@Override
protected Void doInBackground(Void... args) {
String username = mEtxtUsername.getText().toString();
String encodedUserName= "";
try {
encodedUserName= URLEncoder.encode(username, "utf-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String fetchUrl = "http://api.twitter.com/1/users/show.json?screen_name=" + encodedUserName;
DefaultHttpClient httpclient = createHttpClient();
HttpGet httpget = new HttpGet(fetchUrl);
try {
HttpResponse response = httpclient.execute(httpget);
StatusLine statusLine = response.getStatusLine();
mStatusCode = statusLine.getStatusCode();
if (mStatusCode == 200){
mResultString = EntityUtils.toString(response.getEntity());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
mConnectionException = e;
} catch (IOException e) {
e.printStackTrace();
mConnectionException = e;
}
return null;
}
@Override
protected void onPostExecute(Void arg) {
mProgressDialog.dismiss();
if (mStatusCode == 200){
mTwitterUser = new TwitterUser(mResultString);
updateView();
}
else if (mStatusCode == 404){
Toast.makeText(MainActivity.this, "De gevraagde gebruiker bestaat niet.", Toast.LENGTH_LONG).show();
mTwitterUser = null;
updateView();
}
else if (mStatusCode > 0){
Toast.makeText(MainActivity.this, "Er is in verbindingsfout opgetreden met foutcode " + mStatusCode, Toast.LENGTH_LONG).show();
mTwitterUser = null;
updateView();
}
else {
Toast.makeText(MainActivity.this, "Gegevens konden niet worden opgehaald. Controleer uw internetverbinding en probeer het opnieuw (" +mConnectionException.toString() + ")" , Toast.LENGTH_LONG).show();
mTwitterUser = null;
updateView();
}
}
}
}
public class TwitterUser {
String mUserName;
String mWebsite;
String mDescription;
int mFavouritesCount;
public TwitterUser(String jsonString){
try {
JSONObject jSONObject = new JSONObject(jsonString);
mUserName = jSONObject.optString("screen_name");
mWebsite = jSONObject.optString("url");
mDescription = jSONObject.optString("description");
mFavouritesCount = jSONObject.optInt("favourites_count");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getUserName(){
return mUserName;
}
public String getWebsite(){
return mWebsite;
}
public String getDescription(){
return mDescription;
}
public int getFavouritesCount(){
return mFavouritesCount;
}
}
public class TweetsActivity extends Activity {
TextView mTxtvTitle;
ProgressDialog mProgressDialog;
String mUserName;
ArrayList<Tweet> mTweets;
ListView mLvTweets;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tweets);
mTxtvTitle = (TextView) findViewById(R.id.txtvTitle);
mLvTweets = (ListView) findViewById(R.id.lvTweets);
Intent intent = getIntent();
Bundle extrasBundle = intent.getExtras();
mUserName = extrasBundle.getString("twitter_user_name");
updateView();
startDownloadingTweets();
}
private void updateView() {
mTxtvTitle.setText(mUserName);
if (mTweets != null){
TweetsListAdapter tweetsListAdapter = new TweetsListAdapter(this, mTweets);
mLvTweets.setAdapter(tweetsListAdapter);
}
}
private void startDownloadingTweets() {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Bezig met het ophalen van gegevens...");
mProgressDialog.show();
new DownloadTweetsTask().execute();
}
private DefaultHttpClient createHttpClient() {
HttpParams my_httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(my_httpParams, 3000);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
ThreadSafeClientConnManager multiThreadedConnectionManager = new ThreadSafeClientConnManager(my_httpParams, registry);
DefaultHttpClient httpclient = new DefaultHttpClient(multiThreadedConnectionManager, my_httpParams);
return httpclient;
}
private class DownloadTweetsTask extends AsyncTask<Void, Void, Void> {
int mStatusCode = 0;
String mResultString;
Exception mConnectionException;
@Override
protected Void doInBackground(Void... args) {
String encodedUserName= "";
try {
encodedUserName= URLEncoder.encode(mUserName, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String fetchUrl = "http://api.twitter.com/1/statuses/user_timeline.json?include_rts=true&count=30&screen_name=" + encodedUserName;
DefaultHttpClient httpclient = createHttpClient();
HttpGet httpget = new HttpGet(fetchUrl);
try {
HttpResponse response = httpclient.execute(httpget);
StatusLine statusLine = response.getStatusLine();
mStatusCode = statusLine.getStatusCode();
if (mStatusCode == 200){
mResultString = EntityUtils.toString(response.getEntity());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
mConnectionException = e;
} catch (IOException e) {
e.printStackTrace();
mConnectionException = e;
}
return null;
}
@Override
protected void onPostExecute(Void arg) {
mProgressDialog.dismiss();
if (mStatusCode == 200){
processResults(mResultString);
updateView();
}
else if (mStatusCode == 401){
Toast.makeText(TweetsActivity.this, "De timeline van deze gebruiker is niet publiek toegankelijk.", Toast.LENGTH_LONG).show();
}
else if (mStatusCode > 0){
Toast.makeText(TweetsActivity.this, "Er is in verbindingsfout opgetreden met foutcode " + mStatusCode, Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(TweetsActivity.this, "Gegevens konden niet worden opgehaald. Controleer uw internetverbinding en probeer het opnieuw (" +mConnectionException.toString() + ")" , Toast.LENGTH_LONG).show();
}
}
}
private void processResults(String resultString) {
mTweets = new ArrayList<Tweet>();
try {
JSONArray jSONArray = new JSONArray(resultString);
for (int counter = 0; counter < jSONArray.length() ; counter ++){
JSONObject jSONObject = jSONArray.getJSONObject(counter);
Tweet tweet = new Tweet(jSONObject);
mTweets.add(tweet);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
public class TweetsListAdapter extends BaseAdapter {
ArrayList<Tweet> mTweets;
LayoutInflater mInflater;
public TweetsListAdapter(Context context, ArrayList<Tweet> tweets){
mTweets = new ArrayList<Tweet>();
mTweets.addAll(tweets);
notifyDataSetChanged();
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return mTweets.size();
}
public Tweet getItem(int position) {
return mTweets.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.tweet_listitem, null);
holder = new ViewHolder();
holder.mTxtvText = (TextView) convertView.findViewById(R.id.txtvText);
holder.mTxtvCreatedAt = (TextView) convertView.findViewById(R.id.txtvCreatedAt);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Tweet tweet = getItem(position);
holder.mTxtvText.setText(tweet.getText());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm");
String dateString = simpleDateFormat.format(tweet.getCreatedAt());
holder.mTxtvCreatedAt.setText(dateString);
return convertView;
}
private class ViewHolder {
TextView mTxtvText;
TextView mTxtvCreatedAt;
}
}
public class Tweet {
Date mCreatedAt;
String mText;
static SimpleDateFormat sEnglishSimpleDateFormat;
public Tweet(JSONObject jSONObject){
String dateString = jSONObject.optString("created_at");
if (sEnglishSimpleDateFormat == null){
Locale englishLocale = Locale.ENGLISH;
sEnglishSimpleDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZZZ yyyy", englishLocale);
}
try {
mCreatedAt = sEnglishSimpleDateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
mText = jSONObject.optString("text");
}
public Date getCreatedAt(){
return mCreatedAt;
}
public String getText(){
return mText;
}
}
以及发生的错误:
10-18 21:22:49.478: D/dalvikvm(390): GC freed 4935 objects / 312200
bytes in 101ms 10-18 21:22:51.628: I/Resources(390): Loaded time zone
names for en_US in 1769ms. 10-18 21:22:51.938: D/dalvikvm(390): GC
freed 2918 objects / 178312 bytes in 245ms 10-18 21:22:51.948:
D/dalvikvm(390): threadid=17 wakeup: interrupted 10-18 21:22:54.958:
D/AndroidRuntime(390): Shutting down VM 10-18 21:22:54.958:
W/dalvikvm(390): threadid=3: thread exiting with uncaught exception
(group=0x4001b188) 10-18 21:22:54.968: E/AndroidRuntime(390): Uncaught
handler: thread main exiting due to uncaught exception 10-18
21:22:54.988: E/AndroidRuntime(390): java.lang.IllegalStateException:
Could not execute method of the activity 10-18 21:22:54.988:
E/AndroidRuntime(390): at android.view.View$1.onClick(View.java:2031)
10-18 21:22:54.988: E/AndroidRuntime(390): at
android.view.View.performClick(View.java:2364) 10-18 21:22:54.988:
E/AndroidRuntime(390): at
android.view.View.onTouchEvent(View.java:4179) 10-18 21:22:54.988:
E/AndroidRuntime(390): at
android.widget.TextView.onTouchEvent(TextView.java:6541) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.view.View.dispatchTouchEvent(View.java:3709) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884) 10-18
21:22:54.988: E/AndroidRuntime(390): at
com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659)
10-18 21:22:54.988: E/AndroidRuntime(390): at
com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
10-18 21:22:54.988: E/AndroidRuntime(390): at
android.app.Activity.dispatchTouchEvent(Activity.java:2061) 10-18
21:22:54.988: E/AndroidRuntime(390): at
com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
10-18 21:22:54.988: E/AndroidRuntime(390): at
android.view.ViewRoot.handleMessage(ViewRoot.java:1691) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.os.Handler.dispatchMessage(Handler.java:99) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.os.Looper.loop(Looper.java:123) 10-18 21:22:54.988:
E/AndroidRuntime(390): at
android.app.ActivityThread.main(ActivityThread.java:4363) 10-18
21:22:54.988: E/AndroidRuntime(390): at
java.lang.reflect.Method.invokeNative(Native Method) 10-18
21:22:54.988: E/AndroidRuntime(390): at
java.lang.reflect.Method.invoke(Method.java:521) 10-18 21:22:54.988:
E/AndroidRuntime(390): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
10-18 21:22:54.988: E/AndroidRuntime(390): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 10-18
21:22:54.988: E/AndroidRuntime(390): at
dalvik.system.NativeStart.main(Native Method) 10-18 21:22:54.988:
E/AndroidRuntime(390): Caused by:
java.lang.reflect.InvocationTargetException 10-18 21:22:54.988:
E/AndroidRuntime(390): at
com.example.twittertest.MainActivity.showTweets(MainActivity.java:93)
10-18 21:22:54.988: E/AndroidRuntime(390): at
java.lang.reflect.Method.invokeNative(Native Method) 10-18
21:22:54.988: E/AndroidRuntime(390): at
java.lang.reflect.Method.invoke(Method.java:521) 10-18 21:22:54.988:
E/AndroidRuntime(390): at android.view.View$1.onClick(View.java:2026)
10-18 21:22:54.988: E/AndroidRuntime(390): ... 22 more 10-18
21:22:54.988: E/AndroidRuntime(390): Caused by:
android.content.ActivityNotFoundException: Unable to find explicit
activity class
{com.example.twittertest/com.example.twittertest.TweetsActivity}; have
you declared this activity in your AndroidManifest.xml? 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1404)
10-18 21:22:54.988: E/AndroidRuntime(390): at
android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)
10-18 21:22:54.988: E/AndroidRuntime(390): at
android.app.Activity.startActivityForResult(Activity.java:2749) 10-18
21:22:54.988: E/AndroidRuntime(390): at
android.app.Activity.startActivity(Activity.java:2855) 10-18
21:22:54.988: E/AndroidRuntime(390): ... 26 more 10-18 21:22:55.031:
I/dalvikvm(390): threadid=7: reacting to signal 3 10-18 21:22:55.031:
E/dalvikvm(390): Unable to open stack trace file
'/data/anr/traces.txt': Permission denied 10-18 21:22:57.828:
I/Process(390): Sending signal. PID: 390 SIG: 9