错误:没有这样的表用户-活动Android

错误:没有这样的表用户-活动Android,android,twitter,activeandroid,Android,Twitter,Activeandroid,我正在制作一个Twitter客户端,作为学习Android的一种实践,登录和时间轴活动都很好,但当我点击操作栏图标时,它会将我带到一个ComposeTweetActivity.java,在我输入文本(我的推文)并按下推文按钮来撰写推文后,它什么也不做(它应该实际上传到我的Twitter帐户,然后将我返回到我的TimelineActivity.java)。在控制台中,它给出了错误信息: 04-14 18:10:34.797: E/SQLiteLog(998): (1) no such table:

我正在制作一个Twitter客户端,作为学习Android的一种实践,登录和时间轴活动都很好,但当我点击操作栏图标时,它会将我带到一个
ComposeTweetActivity.java
,在我输入文本(我的推文)并按下推文按钮来撰写推文后,它什么也不做(它应该实际上传到我的Twitter帐户,然后将我返回到我的
TimelineActivity.java
)。在控制台中,它给出了错误信息:

04-14 18:10:34.797: E/SQLiteLog(998): (1) no such table: Users

04-14 18:10:34.805: E/SQLiteDatabase(998): android.database.sqlite.SQLiteException: no such table: Users (code 1): , while compiling: INSERT INTO Users(user_name,friends_count,profile_background_image_url,Tweet,user_id,screen_name,Id,tweet_count,profile_image_url,followers_count) VALUES (?,?,?,?,?,?,?,?,?,?)
加上由此产生的许多其他错误。我猜它与Active Android有关,这是我用来保存的数据库。这个项目有很多很多文件,但我会发布
ComposeTweetActivity.java
,因为它有撰写推文按钮(这会导致所有错误)还有
User.java
Tweet.java
,它们是Active Android(我想是吧?)的模型,有所有的表格数据,控制台有所有的错误。如果你需要我发布更多的文件,很乐意为你效劳。非常感谢你的帮助,提前

ComposeTweetActivity.java

package com.codepath.apps.mytwitterapp;

import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.codepath.apps.mytwitterapp.models.Tweet;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.nostra13.universalimageloader.core.ImageLoader;

public class ComposeTweetActivity extends ActionBarActivity {

    private Button    btnCancel,
                      btnTweet;
    private ImageView ivUserImage;
    private TextView  tvUserName;
    private EditText  etNewTweet;

    private boolean   alreadyToasted = false;

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

        setupButtons();
        setupImageView();
        setupTextView();
        setupEditText();
    }

    private void setupButtons() {
        btnCancel = (Button) findViewById(R.id.btnCancel); 
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent();
                setResult(RESULT_CANCELED, i);
                finish(); 
            }
        });

        btnTweet = (Button) findViewById(R.id.btnTweet); 
        btnTweet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String tweetBody = etNewTweet.getText().toString();
                tweet(tweetBody);
            }
        }); 
    }

    private void setupImageView() {
        ivUserImage = (ImageView) findViewById(R.id.ivUserImage);
        Log.d("DEBUG", "TimelineActivity.sScreenName is: " + TimelineActivity.getScreenName());
        Log.d("DEBUG", "TimelineActivity.sImageUrl just before execution of "
                     + "ImageLoader.getInstance().displayImage(mImageUrl, mIvUserImage) is: " 
                     + TimelineActivity.getUserImageUrl());
        ImageLoader.getInstance().displayImage(TimelineActivity.getUserImageUrl(), ivUserImage);
    }

    private void setupTextView() {
        tvUserName = (TextView) findViewById(R.id.tvUserName); 
        tvUserName.setText("@" + TimelineActivity.getScreenName()); 
    }

    private void setupEditText() {
        etNewTweet = (EditText) findViewById(R.id.etNewTweet);  

        // Show soft keyboard when EditText field requests focus
        if (etNewTweet.requestFocus()) {
            InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            mgr.showSoftInput(etNewTweet, InputMethodManager.SHOW_IMPLICIT); 
        }

        etNewTweet.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!alreadyToasted && s.length() == 140) {
                    Toast.makeText(ComposeTweetActivity.this, "You've reached the 140 character"
                            + " limit", Toast.LENGTH_LONG).show(); 
                    alreadyToasted = true; 
                }
                else if (s.length() > 140) {
                    etNewTweet.setTextColor(Color.RED); 
                } else {
                    etNewTweet.setTextColor(Color.BLACK); 
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

            @Override
            public void afterTextChanged(Editable s) { }
        });

    }

    private void tweet(String tweetBody) {
        MyTwitterApp.getRestClient().postTweet(tweetBody, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, JSONObject jsonTweetResponse) {
                Log.d("DEBUG", "Called onSuccess() in tweet()."); 
                Tweet newTweet = Tweet.fromJson(jsonTweetResponse); 
                new AsyncTweetSave().execute(newTweet); 
                Intent i = new Intent();
                i.putExtra("new_tweet", newTweet);
                setResult(RESULT_OK, i);
                finish(); 
            }   

            @Override
            public void onFailure(Throwable e, JSONObject error) {
                Log.d("DEBUG", "Called onFailure() in getUserScreenName(). Failure message: " 
                                + AsyncHttpResponseHandler.FAILURE_MESSAGE);
                Log.e("ERROR", e.getMessage());
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.compose_tweet, menu);
        return true;
    }
}
package com.codepath.apps.mytwitterapp.models;

import java.io.Serializable;
import java.util.List;

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

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;
import com.codepath.apps.mytwitterapp.UserAccountSettings;
import com.codepath.apps.mytwitterapp.UserInfo;

/**
 * Class acts as a Java-representation of a single user retrieved as a JSONObject from the 
 * Twitter REST API v1.1. Fields are as specified in the API Users object documentation. 
 */
@Table(name = "Users")
public class User extends Model implements Serializable {

    @Column(name = "user_name")
    private String name;
    @Column(name = "user_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
    private long   userId;                      // User ID
    @Column(name = "screen_name")
    private String screenName;
    @Column(name = "profile_image_url")
    private String profileImageUrl;
    @Column(name = "profile_background_image_url")
    private String profileBackgroundImageUrl;               
    @Column(name = "tweet_count")
    private int    tweetCount;                  // Referred to as statuses_count in Twitter API
    @Column(name = "followers_count")
    private int    followersCount;
    @Column(name = "friends_count") 
    private int    friendsCount;

    @Column(name = "Tweet")                     // Created for ActiveAndroid to establish a direct  
    private Tweet  tweet;                       // relationship with the Tweets table

    public User() {                             // Empty-argument constructor required by ActiveAndroid
        super(); 
    }

    public String getName() {
        return name;
    }

    public long getUserId() {
        return userId;
    }

    public String getScreenName() {
        return screenName;
    }

    public String getProfileImageUrl() {
        return profileImageUrl;
    }

    public String getProfileBackgroundImageUrl() {
        return profileBackgroundImageUrl;
    }

    public int getNumTweets() {
        return tweetCount;
    }

    public int getFollowersCount() {
        return followersCount;
    }

    public int getFriendsCount() {
        return friendsCount;
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the 
    // UserAccountSettings table
    public List<UserAccountSettings> getUserAccountSettings() {
        return getMany(UserAccountSettings.class, "Users");
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the 
    // UserInfo table
    public List<UserInfo> getUserInfo() {
        return getMany(UserInfo.class, "Users");
    }

    public static User fromJson(JSONObject jsonObject) {
        User u = new User();
        try {
            u.name                   = jsonObject.getString("name");
            u.userId                         = jsonObject.getLong("id");
            u.screenName                 = jsonObject.getString("screen_name");
            u.profileImageUrl            = jsonObject.getString("profile_image_url");
            u.profileBackgroundImageUrl = jsonObject.getString("profile_background_image_url");
            u.tweetCount                 = jsonObject.getInt("statuses_count");
            u.followersCount             = jsonObject.getInt("followers_count");
            u.friendsCount           = jsonObject.getInt("friends_count");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return u;
    }
}
package com.codepath.apps.mytwitterapp.models;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

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

import android.util.Log;

import com.activeandroid.ActiveAndroid;
import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

/**
 * Class acts as a Java-representation of a single tweet retrieved as a JSONObject from the 
 * Twitter REST API v1.1. Fields are as specified in the API Tweets object documentation. 
 */
@Table(name = "Tweets")
public class Tweet extends Model implements Serializable {

    @Column(name = "max_id")
    private static long maxId;  // ID of the last (ie, earliest-timestamped) tweet to be processed in the current JSONArray

    @Column(name = "tweet_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
    private long        tweetId;    // Tweet ID
    @Column(name = "created_at")
    private String      createdAt; 
    @Column(name = "tweet_body")
    private String      body;
    @Column(name = "favorited")
    private boolean     favorited;
    @Column(name = "retweeted")
    private boolean     retweeted;
    @Column(name = "user")
    private User        user;

    public Tweet() {                // Empty-argument constructor required by ActiveAndroid
        super(); 
    }   

    public static long getMaxId() {
        return maxId;
    }

    public static String getMaxIdAsString() {
        return String.valueOf(maxId);
    }

    public static void decrementMaxId() {
        maxId -= 1; 
    }

    public long getTweetId() {
        return tweetId;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public String getBody() {
        return body;
    }

    public boolean isFavorited() {
        return favorited;
    }

    public boolean isRetweeted() {
        return retweeted;
    }

    public User getUser() {
        return user;
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the Users table
    public List<User> getUsers() {
        return getMany(User.class, "Tweets");
    }

    public static Tweet fromJson(JSONObject jsonObject) {
        Tweet tweet = new Tweet();
        try {
            tweet.tweetId        = jsonObject.getLong("id");
            tweet.createdAt = jsonObject.getString("created_at");
            tweet.body   = jsonObject.getString("text");
            tweet.favorited = jsonObject.getBoolean("favorited");
            tweet.retweeted = jsonObject.getBoolean("retweeted");
            tweet.user   = User.fromJson(jsonObject.getJSONObject("user"));
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
        return tweet;
    }

    public static ArrayList<Tweet> fromJson(JSONArray jsonArray) {
        ArrayList<Tweet> tweets = new ArrayList<Tweet>(jsonArray.length());

        for (int i=0; i < jsonArray.length(); i++) {
            JSONObject tweetJson = null;
            try {
                tweetJson = jsonArray.getJSONObject(i);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }

            Tweet tweet = Tweet.fromJson(tweetJson);
            if (tweet != null) {
                maxId = tweet.getTweetId();
                tweets.add(tweet);
            }

        }
        return tweets;
    }

    public static void saveTweet(Tweet tweet) {
        tweet.user.save();
        tweet.save();
    }

    public static void saveTweets(ArrayList<Tweet> tweets) {
        ActiveAndroid.beginTransaction();
        try {
            for (int i = 0; i < tweets.size(); i++) {
                Tweet t = tweets.get(i);
                Log.d("DEBUG", "Inside saveTweets(ArrayList<Tweet>), current tweet is: "  + t.toString());
                if (t != null) {
                    if (t.user != null) {
                        t.user.save();
                    } 
                    t.save(); 
                }
            }
            ActiveAndroid.setTransactionSuccessful();
        } finally {
            ActiveAndroid.endTransaction(); 
        }
    } 
}
User.java

package com.codepath.apps.mytwitterapp;

import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.codepath.apps.mytwitterapp.models.Tweet;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.nostra13.universalimageloader.core.ImageLoader;

public class ComposeTweetActivity extends ActionBarActivity {

    private Button    btnCancel,
                      btnTweet;
    private ImageView ivUserImage;
    private TextView  tvUserName;
    private EditText  etNewTweet;

    private boolean   alreadyToasted = false;

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

        setupButtons();
        setupImageView();
        setupTextView();
        setupEditText();
    }

    private void setupButtons() {
        btnCancel = (Button) findViewById(R.id.btnCancel); 
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent();
                setResult(RESULT_CANCELED, i);
                finish(); 
            }
        });

        btnTweet = (Button) findViewById(R.id.btnTweet); 
        btnTweet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String tweetBody = etNewTweet.getText().toString();
                tweet(tweetBody);
            }
        }); 
    }

    private void setupImageView() {
        ivUserImage = (ImageView) findViewById(R.id.ivUserImage);
        Log.d("DEBUG", "TimelineActivity.sScreenName is: " + TimelineActivity.getScreenName());
        Log.d("DEBUG", "TimelineActivity.sImageUrl just before execution of "
                     + "ImageLoader.getInstance().displayImage(mImageUrl, mIvUserImage) is: " 
                     + TimelineActivity.getUserImageUrl());
        ImageLoader.getInstance().displayImage(TimelineActivity.getUserImageUrl(), ivUserImage);
    }

    private void setupTextView() {
        tvUserName = (TextView) findViewById(R.id.tvUserName); 
        tvUserName.setText("@" + TimelineActivity.getScreenName()); 
    }

    private void setupEditText() {
        etNewTweet = (EditText) findViewById(R.id.etNewTweet);  

        // Show soft keyboard when EditText field requests focus
        if (etNewTweet.requestFocus()) {
            InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            mgr.showSoftInput(etNewTweet, InputMethodManager.SHOW_IMPLICIT); 
        }

        etNewTweet.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!alreadyToasted && s.length() == 140) {
                    Toast.makeText(ComposeTweetActivity.this, "You've reached the 140 character"
                            + " limit", Toast.LENGTH_LONG).show(); 
                    alreadyToasted = true; 
                }
                else if (s.length() > 140) {
                    etNewTweet.setTextColor(Color.RED); 
                } else {
                    etNewTweet.setTextColor(Color.BLACK); 
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

            @Override
            public void afterTextChanged(Editable s) { }
        });

    }

    private void tweet(String tweetBody) {
        MyTwitterApp.getRestClient().postTweet(tweetBody, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, JSONObject jsonTweetResponse) {
                Log.d("DEBUG", "Called onSuccess() in tweet()."); 
                Tweet newTweet = Tweet.fromJson(jsonTweetResponse); 
                new AsyncTweetSave().execute(newTweet); 
                Intent i = new Intent();
                i.putExtra("new_tweet", newTweet);
                setResult(RESULT_OK, i);
                finish(); 
            }   

            @Override
            public void onFailure(Throwable e, JSONObject error) {
                Log.d("DEBUG", "Called onFailure() in getUserScreenName(). Failure message: " 
                                + AsyncHttpResponseHandler.FAILURE_MESSAGE);
                Log.e("ERROR", e.getMessage());
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.compose_tweet, menu);
        return true;
    }
}
package com.codepath.apps.mytwitterapp.models;

import java.io.Serializable;
import java.util.List;

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

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;
import com.codepath.apps.mytwitterapp.UserAccountSettings;
import com.codepath.apps.mytwitterapp.UserInfo;

/**
 * Class acts as a Java-representation of a single user retrieved as a JSONObject from the 
 * Twitter REST API v1.1. Fields are as specified in the API Users object documentation. 
 */
@Table(name = "Users")
public class User extends Model implements Serializable {

    @Column(name = "user_name")
    private String name;
    @Column(name = "user_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
    private long   userId;                      // User ID
    @Column(name = "screen_name")
    private String screenName;
    @Column(name = "profile_image_url")
    private String profileImageUrl;
    @Column(name = "profile_background_image_url")
    private String profileBackgroundImageUrl;               
    @Column(name = "tweet_count")
    private int    tweetCount;                  // Referred to as statuses_count in Twitter API
    @Column(name = "followers_count")
    private int    followersCount;
    @Column(name = "friends_count") 
    private int    friendsCount;

    @Column(name = "Tweet")                     // Created for ActiveAndroid to establish a direct  
    private Tweet  tweet;                       // relationship with the Tweets table

    public User() {                             // Empty-argument constructor required by ActiveAndroid
        super(); 
    }

    public String getName() {
        return name;
    }

    public long getUserId() {
        return userId;
    }

    public String getScreenName() {
        return screenName;
    }

    public String getProfileImageUrl() {
        return profileImageUrl;
    }

    public String getProfileBackgroundImageUrl() {
        return profileBackgroundImageUrl;
    }

    public int getNumTweets() {
        return tweetCount;
    }

    public int getFollowersCount() {
        return followersCount;
    }

    public int getFriendsCount() {
        return friendsCount;
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the 
    // UserAccountSettings table
    public List<UserAccountSettings> getUserAccountSettings() {
        return getMany(UserAccountSettings.class, "Users");
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the 
    // UserInfo table
    public List<UserInfo> getUserInfo() {
        return getMany(UserInfo.class, "Users");
    }

    public static User fromJson(JSONObject jsonObject) {
        User u = new User();
        try {
            u.name                   = jsonObject.getString("name");
            u.userId                         = jsonObject.getLong("id");
            u.screenName                 = jsonObject.getString("screen_name");
            u.profileImageUrl            = jsonObject.getString("profile_image_url");
            u.profileBackgroundImageUrl = jsonObject.getString("profile_background_image_url");
            u.tweetCount                 = jsonObject.getInt("statuses_count");
            u.followersCount             = jsonObject.getInt("followers_count");
            u.friendsCount           = jsonObject.getInt("friends_count");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return u;
    }
}
package com.codepath.apps.mytwitterapp.models;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

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

import android.util.Log;

import com.activeandroid.ActiveAndroid;
import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

/**
 * Class acts as a Java-representation of a single tweet retrieved as a JSONObject from the 
 * Twitter REST API v1.1. Fields are as specified in the API Tweets object documentation. 
 */
@Table(name = "Tweets")
public class Tweet extends Model implements Serializable {

    @Column(name = "max_id")
    private static long maxId;  // ID of the last (ie, earliest-timestamped) tweet to be processed in the current JSONArray

    @Column(name = "tweet_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
    private long        tweetId;    // Tweet ID
    @Column(name = "created_at")
    private String      createdAt; 
    @Column(name = "tweet_body")
    private String      body;
    @Column(name = "favorited")
    private boolean     favorited;
    @Column(name = "retweeted")
    private boolean     retweeted;
    @Column(name = "user")
    private User        user;

    public Tweet() {                // Empty-argument constructor required by ActiveAndroid
        super(); 
    }   

    public static long getMaxId() {
        return maxId;
    }

    public static String getMaxIdAsString() {
        return String.valueOf(maxId);
    }

    public static void decrementMaxId() {
        maxId -= 1; 
    }

    public long getTweetId() {
        return tweetId;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public String getBody() {
        return body;
    }

    public boolean isFavorited() {
        return favorited;
    }

    public boolean isRetweeted() {
        return retweeted;
    }

    public User getUser() {
        return user;
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the Users table
    public List<User> getUsers() {
        return getMany(User.class, "Tweets");
    }

    public static Tweet fromJson(JSONObject jsonObject) {
        Tweet tweet = new Tweet();
        try {
            tweet.tweetId        = jsonObject.getLong("id");
            tweet.createdAt = jsonObject.getString("created_at");
            tweet.body   = jsonObject.getString("text");
            tweet.favorited = jsonObject.getBoolean("favorited");
            tweet.retweeted = jsonObject.getBoolean("retweeted");
            tweet.user   = User.fromJson(jsonObject.getJSONObject("user"));
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
        return tweet;
    }

    public static ArrayList<Tweet> fromJson(JSONArray jsonArray) {
        ArrayList<Tweet> tweets = new ArrayList<Tweet>(jsonArray.length());

        for (int i=0; i < jsonArray.length(); i++) {
            JSONObject tweetJson = null;
            try {
                tweetJson = jsonArray.getJSONObject(i);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }

            Tweet tweet = Tweet.fromJson(tweetJson);
            if (tweet != null) {
                maxId = tweet.getTweetId();
                tweets.add(tweet);
            }

        }
        return tweets;
    }

    public static void saveTweet(Tweet tweet) {
        tweet.user.save();
        tweet.save();
    }

    public static void saveTweets(ArrayList<Tweet> tweets) {
        ActiveAndroid.beginTransaction();
        try {
            for (int i = 0; i < tweets.size(); i++) {
                Tweet t = tweets.get(i);
                Log.d("DEBUG", "Inside saveTweets(ArrayList<Tweet>), current tweet is: "  + t.toString());
                if (t != null) {
                    if (t.user != null) {
                        t.user.save();
                    } 
                    t.save(); 
                }
            }
            ActiveAndroid.setTransactionSuccessful();
        } finally {
            ActiveAndroid.endTransaction(); 
        }
    } 
}
package com.codepath.apps.mytwitterapp.models;
导入java.io.Serializable;
导入java.util.List;
导入org.json.JSONException;
导入org.json.JSONObject;
导入com.activeandroid.Model;
导入com.activeandroid.annotation.Column;
导入com.activeandroid.annotation.Table;
导入com.codepath.apps.mytwitterapp.UserAccountSettings;
导入com.codepath.apps.mytwitterapp.UserInfo;
/**
*类充当单个用户的Java表示,该用户作为JSONObject从
*TwitterRESTAPI v1.1。字段在API用户对象文档中指定。
*/
@表(name=“Users”)
公共类用户扩展模型实现可序列化{
@列(name=“user\u name”)
私有字符串名称;
@列(name=“user\u id”,unique=true,onUniqueConflict=Column.ConflictAction.REPLACE)
私有长用户ID;//用户ID
@列(name=“screen\u name”)
私有字符串屏幕名;
@列(name=“profile\u image\u url”)
私有字符串profileImageUrl;
@列(name=“profile\u background\u image\u url”)
私有字符串profileBackgroundImageUrl;
@列(name=“tweet\u count”)
private int tweetCount;//在Twitter API中称为status\u count
@列(name=“followers\u count”)
私人内部跟踪计数;
@列(name=“friends\u count”)
私人国际友谊俱乐部;
@Column(name=“Tweet”)//为ActiveAndroid创建以建立直接
私有Tweet;//与Tweets表的关系
public User(){//ActiveAndroid所需的空参数构造函数
超级();
}
公共字符串getName(){
返回名称;
}
公共长getUserId(){
返回用户标识;
}
公共字符串getScreenName(){
返回屏幕名称;
}
公共字符串getProfileImageUrl(){
返回profileImageUrl;
}
公共字符串getProfileBackgroundImageUrl(){
返回profileBackgroundImageUrl;
}
public int getNumTweets(){
返回tweet计数;
}
public int getFollowersCount(){
返回跟随者计数;
}
public int getFriendsCount(){
回归友谊;
}
//ActiveAndroid的可选助手方法,用于与
//UserAccountSettings表
公共列表getUserAccountSettings(){
返回getMany(UserAccountSettings.class,“Users”);
}
//ActiveAndroid的可选助手方法,用于与
//用户信息表
公共列表getUserInfo(){
返回getMany(UserInfo.class,“Users”);
}
来自JSON的公共静态用户(JSONObject JSONObject){
用户u=新用户();
试一试{
u、 name=jsonObject.getString(“name”);
u、 userId=jsonObject.getLong(“id”);
u、 screenName=jsonObject.getString(“屏幕名称”);
u、 profileImageUrl=jsonObject.getString(“profile\u image\u url”);
u、 profileBackgroundImageUrl=jsonObject.getString(“profile\u background\u image\u url”);
u、 tweetCount=jsonObject.getInt(“状态计数”);
u、 followerscont=jsonObject.getInt(“followers_count”);
u、 friendsCount=jsonObject.getInt(“friends_count”);
}捕获(JSONException e){
e、 printStackTrace();
}
返回u;
}
}
Tweet.java

package com.codepath.apps.mytwitterapp;

import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.codepath.apps.mytwitterapp.models.Tweet;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.nostra13.universalimageloader.core.ImageLoader;

public class ComposeTweetActivity extends ActionBarActivity {

    private Button    btnCancel,
                      btnTweet;
    private ImageView ivUserImage;
    private TextView  tvUserName;
    private EditText  etNewTweet;

    private boolean   alreadyToasted = false;

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

        setupButtons();
        setupImageView();
        setupTextView();
        setupEditText();
    }

    private void setupButtons() {
        btnCancel = (Button) findViewById(R.id.btnCancel); 
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent();
                setResult(RESULT_CANCELED, i);
                finish(); 
            }
        });

        btnTweet = (Button) findViewById(R.id.btnTweet); 
        btnTweet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String tweetBody = etNewTweet.getText().toString();
                tweet(tweetBody);
            }
        }); 
    }

    private void setupImageView() {
        ivUserImage = (ImageView) findViewById(R.id.ivUserImage);
        Log.d("DEBUG", "TimelineActivity.sScreenName is: " + TimelineActivity.getScreenName());
        Log.d("DEBUG", "TimelineActivity.sImageUrl just before execution of "
                     + "ImageLoader.getInstance().displayImage(mImageUrl, mIvUserImage) is: " 
                     + TimelineActivity.getUserImageUrl());
        ImageLoader.getInstance().displayImage(TimelineActivity.getUserImageUrl(), ivUserImage);
    }

    private void setupTextView() {
        tvUserName = (TextView) findViewById(R.id.tvUserName); 
        tvUserName.setText("@" + TimelineActivity.getScreenName()); 
    }

    private void setupEditText() {
        etNewTweet = (EditText) findViewById(R.id.etNewTweet);  

        // Show soft keyboard when EditText field requests focus
        if (etNewTweet.requestFocus()) {
            InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            mgr.showSoftInput(etNewTweet, InputMethodManager.SHOW_IMPLICIT); 
        }

        etNewTweet.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!alreadyToasted && s.length() == 140) {
                    Toast.makeText(ComposeTweetActivity.this, "You've reached the 140 character"
                            + " limit", Toast.LENGTH_LONG).show(); 
                    alreadyToasted = true; 
                }
                else if (s.length() > 140) {
                    etNewTweet.setTextColor(Color.RED); 
                } else {
                    etNewTweet.setTextColor(Color.BLACK); 
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

            @Override
            public void afterTextChanged(Editable s) { }
        });

    }

    private void tweet(String tweetBody) {
        MyTwitterApp.getRestClient().postTweet(tweetBody, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, JSONObject jsonTweetResponse) {
                Log.d("DEBUG", "Called onSuccess() in tweet()."); 
                Tweet newTweet = Tweet.fromJson(jsonTweetResponse); 
                new AsyncTweetSave().execute(newTweet); 
                Intent i = new Intent();
                i.putExtra("new_tweet", newTweet);
                setResult(RESULT_OK, i);
                finish(); 
            }   

            @Override
            public void onFailure(Throwable e, JSONObject error) {
                Log.d("DEBUG", "Called onFailure() in getUserScreenName(). Failure message: " 
                                + AsyncHttpResponseHandler.FAILURE_MESSAGE);
                Log.e("ERROR", e.getMessage());
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.compose_tweet, menu);
        return true;
    }
}
package com.codepath.apps.mytwitterapp.models;

import java.io.Serializable;
import java.util.List;

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

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;
import com.codepath.apps.mytwitterapp.UserAccountSettings;
import com.codepath.apps.mytwitterapp.UserInfo;

/**
 * Class acts as a Java-representation of a single user retrieved as a JSONObject from the 
 * Twitter REST API v1.1. Fields are as specified in the API Users object documentation. 
 */
@Table(name = "Users")
public class User extends Model implements Serializable {

    @Column(name = "user_name")
    private String name;
    @Column(name = "user_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
    private long   userId;                      // User ID
    @Column(name = "screen_name")
    private String screenName;
    @Column(name = "profile_image_url")
    private String profileImageUrl;
    @Column(name = "profile_background_image_url")
    private String profileBackgroundImageUrl;               
    @Column(name = "tweet_count")
    private int    tweetCount;                  // Referred to as statuses_count in Twitter API
    @Column(name = "followers_count")
    private int    followersCount;
    @Column(name = "friends_count") 
    private int    friendsCount;

    @Column(name = "Tweet")                     // Created for ActiveAndroid to establish a direct  
    private Tweet  tweet;                       // relationship with the Tweets table

    public User() {                             // Empty-argument constructor required by ActiveAndroid
        super(); 
    }

    public String getName() {
        return name;
    }

    public long getUserId() {
        return userId;
    }

    public String getScreenName() {
        return screenName;
    }

    public String getProfileImageUrl() {
        return profileImageUrl;
    }

    public String getProfileBackgroundImageUrl() {
        return profileBackgroundImageUrl;
    }

    public int getNumTweets() {
        return tweetCount;
    }

    public int getFollowersCount() {
        return followersCount;
    }

    public int getFriendsCount() {
        return friendsCount;
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the 
    // UserAccountSettings table
    public List<UserAccountSettings> getUserAccountSettings() {
        return getMany(UserAccountSettings.class, "Users");
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the 
    // UserInfo table
    public List<UserInfo> getUserInfo() {
        return getMany(UserInfo.class, "Users");
    }

    public static User fromJson(JSONObject jsonObject) {
        User u = new User();
        try {
            u.name                   = jsonObject.getString("name");
            u.userId                         = jsonObject.getLong("id");
            u.screenName                 = jsonObject.getString("screen_name");
            u.profileImageUrl            = jsonObject.getString("profile_image_url");
            u.profileBackgroundImageUrl = jsonObject.getString("profile_background_image_url");
            u.tweetCount                 = jsonObject.getInt("statuses_count");
            u.followersCount             = jsonObject.getInt("followers_count");
            u.friendsCount           = jsonObject.getInt("friends_count");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return u;
    }
}
package com.codepath.apps.mytwitterapp.models;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

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

import android.util.Log;

import com.activeandroid.ActiveAndroid;
import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

/**
 * Class acts as a Java-representation of a single tweet retrieved as a JSONObject from the 
 * Twitter REST API v1.1. Fields are as specified in the API Tweets object documentation. 
 */
@Table(name = "Tweets")
public class Tweet extends Model implements Serializable {

    @Column(name = "max_id")
    private static long maxId;  // ID of the last (ie, earliest-timestamped) tweet to be processed in the current JSONArray

    @Column(name = "tweet_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
    private long        tweetId;    // Tweet ID
    @Column(name = "created_at")
    private String      createdAt; 
    @Column(name = "tweet_body")
    private String      body;
    @Column(name = "favorited")
    private boolean     favorited;
    @Column(name = "retweeted")
    private boolean     retweeted;
    @Column(name = "user")
    private User        user;

    public Tweet() {                // Empty-argument constructor required by ActiveAndroid
        super(); 
    }   

    public static long getMaxId() {
        return maxId;
    }

    public static String getMaxIdAsString() {
        return String.valueOf(maxId);
    }

    public static void decrementMaxId() {
        maxId -= 1; 
    }

    public long getTweetId() {
        return tweetId;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public String getBody() {
        return body;
    }

    public boolean isFavorited() {
        return favorited;
    }

    public boolean isRetweeted() {
        return retweeted;
    }

    public User getUser() {
        return user;
    }

    // Optional helper method for ActiveAndroid to establish a direct relationship with the Users table
    public List<User> getUsers() {
        return getMany(User.class, "Tweets");
    }

    public static Tweet fromJson(JSONObject jsonObject) {
        Tweet tweet = new Tweet();
        try {
            tweet.tweetId        = jsonObject.getLong("id");
            tweet.createdAt = jsonObject.getString("created_at");
            tweet.body   = jsonObject.getString("text");
            tweet.favorited = jsonObject.getBoolean("favorited");
            tweet.retweeted = jsonObject.getBoolean("retweeted");
            tweet.user   = User.fromJson(jsonObject.getJSONObject("user"));
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
        return tweet;
    }

    public static ArrayList<Tweet> fromJson(JSONArray jsonArray) {
        ArrayList<Tweet> tweets = new ArrayList<Tweet>(jsonArray.length());

        for (int i=0; i < jsonArray.length(); i++) {
            JSONObject tweetJson = null;
            try {
                tweetJson = jsonArray.getJSONObject(i);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }

            Tweet tweet = Tweet.fromJson(tweetJson);
            if (tweet != null) {
                maxId = tweet.getTweetId();
                tweets.add(tweet);
            }

        }
        return tweets;
    }

    public static void saveTweet(Tweet tweet) {
        tweet.user.save();
        tweet.save();
    }

    public static void saveTweets(ArrayList<Tweet> tweets) {
        ActiveAndroid.beginTransaction();
        try {
            for (int i = 0; i < tweets.size(); i++) {
                Tweet t = tweets.get(i);
                Log.d("DEBUG", "Inside saveTweets(ArrayList<Tweet>), current tweet is: "  + t.toString());
                if (t != null) {
                    if (t.user != null) {
                        t.user.save();
                    } 
                    t.save(); 
                }
            }
            ActiveAndroid.setTransactionSuccessful();
        } finally {
            ActiveAndroid.endTransaction(); 
        }
    } 
}
package com.codepath.apps.mytwitterapp.models;
导入java.io.Serializable;
导入java.util.ArrayList;
导入java.util.List;
导入org.json.JSONArray;
导入org.json.JSONException;
导入org.json.JSONObject;
导入android.util.Log;
导入com.activeandroid.activeandroid;
导入com.activeandroid.Model;
导入com.activeandroid.annotation.Column;
导入com.activeandroid.annotation.Table;
/**
*类充当单个tweet的Java表示形式,该tweet作为JSONObject从
*TwitterRESTAPI v1.1。字段在API Tweets对象文档中指定。
*/
@表(name=“Tweets”)
公共类Tweet扩展模型实现了可序列化{
@列(name=“max\u id”)
private static long maxId;//当前JSONArray中要处理的最后一条(即最早的时间戳)tweet的ID
@Column(name=“tweet\u id”,unique=true,onUniqueConflict=Column.ConflictAction.REPLACE)
私有长tweetId;//Tweet ID
@列(name=“created_at”)
私有字符串createdAt;
@列(name=“tweet\u body”)
私有字符串体;
@列(name=“favorited”)
私有布尔优先;
@列(名称)