单击按钮时关闭简单聊天客户端应用程序

时间:2016-07-29 02:35:10

标签: android parse-platform parse-server

我正在学习如何使用parse创建聊天客户端的教程。链接:https://github.com/codepath/android_guides/wiki/Building-Simple-Chat-Client-with-Parse当我在我的应用程序中按发送时,它说“parseapp”已停止。我是一名新程序员,不确定为什么它不起作用。我的代码中没有错误。虽然它必须与按下按钮时有关,或者有一些未使用的变量。请帮忙!提前谢谢。

以下是Actvity的主要代码,我认为该代码最有可能出现问题:

public class ChatActivity extends AppCompatActivity {
static final String TAG = ChatActivity.class.getSimpleName();
static final int MAX_CHAT_MESSAGES_TO_SHOW = 500;

static final String USER_ID_KEY = "userId";
static final String BODY_KEY = "body";

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);


    Parse.initialize(new Parse.Configuration.Builder(this)

            .applicationId("indexApp")
            .clientKey(null)
            .server("http://45.55.25.242:8000/parse/") // The trailing slash is important.



            .build()
    );

    // User login
    if (ParseUser.getCurrentUser() != null) { // start with existing user
        startWithCurrentUser();
    } else { // If not logged in, login as a new anonymous user
        login();
    }
}



// Get the userId from the cached currentUser object
void startWithCurrentUser() {
    // TODO:
    setupMessagePosting();
    {
        // Find the text field and button
        etMessage = (EditText) findViewById(R.id.etMessage);
        btSend = (Button) findViewById(R.id.btSend);
        lvChat = (ListView) findViewById(R.id.lvChat);
        mMessages = new ArrayList<>();
        // Automatically scroll to the bottom when a data set change notification is received and only if the last item is already visible on screen. Don't scroll to the bottom otherwise.
        lvChat.setTranscriptMode(1);
        mFirstLoad = true;
        final String userId = ParseUser.getCurrentUser().getObjectId();
        mAdapter = new ChatListAdapter(ChatActivity.this, userId, mMessages);
        lvChat.setAdapter(mAdapter);
        // When send button is clicked, create message object on Parse
        btSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String data = etMessage.getText().toString();
                ParseObject message = ParseObject.create("Message");
                message.put(Message.USER_ID_KEY, userId);
                message.put(Message.BODY_KEY, data);
                message.saveInBackground(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        Toast.makeText(ChatActivity.this, "Successfully created message on Parse",
                                Toast.LENGTH_SHORT).show();
                        refreshMessages();
                    }
                });
                etMessage.setText(null);
            }
        });
    }
}

    // Query messages from Parse so we can load them into the chat adapter

    void refreshMessages() {
        // Construct query to execute
        ParseQuery<Message> query = ParseQuery.getQuery(Message.class);
        // Configure limit and sort order
        query.setLimit(MAX_CHAT_MESSAGES_TO_SHOW);
        query.orderByAscending("createdAt");
        // Execute query to fetch all messages from Parse asynchronously
        // This is equivalent to a SELECT query with SQL
        query.findInBackground(new FindCallback<Message>() {
            public void done(List<Message> messages, ParseException e) {
                if (e == null) {
                    mMessages.clear();
                    mMessages.addAll(messages);
                    mAdapter.notifyDataSetChanged(); // update adapter
                    // Scroll to the bottom of the list on initial load
                    if (mFirstLoad) {
                        lvChat.setSelection(mAdapter.getCount() - 1);
                        mFirstLoad = false;
                    }
                } else {
                    Log.e("message", "Error Loading Messages" + e);
                }
            }
        });
    }

// Create an anonymous user using ParseAnonymousUtils and set sUserId
void login() {
    ParseAnonymousUtils.logIn(new LogInCallback() {
        @Override
        public void done(ParseUser user, ParseException e) {
            if (e != null) {
                Log.e(TAG, "Anonymous login failed: ", e);
            } else {
                startWithCurrentUser();
            }
        }
    });
}

EditText etMessage;
Button btSend;

ListView lvChat;
ArrayList<Message> mMessages;
ChatListAdapter mAdapter;
// Keep track of initial load to scroll to the bottom of the ListView
boolean mFirstLoad;

void setupMessagePosting() {
    // Find the text field and button
    etMessage = (EditText) findViewById(R.id.etMessage);
    btSend = (Button) findViewById(R.id.btSend);
    // When send button is clicked, create message object on Parse
    btSend.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String data = etMessage.getText().toString();
            ParseObject message = ParseObject.create("Message");
            message.put(Message.USER_ID_KEY,    ParseUser.getCurrentUser().getObjectId());
            message.put(Message.BODY_KEY, data);
            message.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException e) {
                    Toast.makeText(ChatActivity.this, "Successfully created message on Parse",
                            Toast.LENGTH_SHORT).show();
                }
            });
            etMessage.setText(null);
        }
    });
}

// Create a handler which can run code periodically
static final int POLL_INTERVAL = 1000; // milliseconds
Handler mHandler = new Handler();  // android.os.Handler
Runnable mRefreshMessagesRunnable = new Runnable() {
    @Override
    public void run() {
        refreshMessages();
        mHandler.postDelayed(this, POLL_INTERVAL);
            setContentView(R.layout.activity_chat);
            if (ParseUser.getCurrentUser() != null) {
                startWithCurrentUser();
            } else {
                login();
            }
            mHandler.postDelayed(mRefreshMessagesRunnable, POLL_INTERVAL);
        }

};

}

这是布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.patri.parseapp.ChatActivity">
<ListView
    android:id="@+id/lvChat"
    android:transcriptMode="alwaysScroll"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_above="@+id/rlSend"
    android:layout_width="wrap_content"
    android:layout_height="match_parent" />
<RelativeLayout
    android:id="@+id/rlSend"
    android:layout_alignParentBottom="true"
    android:layout_width="match_parent"
    android:paddingTop="5dp"
    android:paddingBottom="10dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:layout_height="wrap_content" >
    <EditText
        android:id="@+id/etMessage"
        android:layout_toLeftOf="@+id/btSend"
        android:layout_alignBottom="@+id/btSend"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:hint="hint"
        android:inputType="textShortMessage"
        android:imeOptions="actionSend"
        />
    <Button
        android:id="@+id/btSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical|right"
        android:paddingRight="10dp"
        android:layout_alignParentRight="true"
        android:text="send"
        android:textSize="18sp" >
    </Button>
</RelativeLayout>
</RelativeLayout>

这是我的适配器:

public class ChatListAdapter extends ArrayAdapter<Message> {
private String mUserId;

public ChatListAdapter(Context context, String userId, List<Message> messages) {
    super(context, 0, messages);
    this.mUserId = userId;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).
                inflate(R.layout.chat_item, parent, false);
        final ViewHolder holder = new ViewHolder();
        holder.imageOther = (ImageView)convertView.findViewById(R.id.ivProfileOther);
        holder.imageMe = (ImageView)convertView.findViewById(R.id.ivProfileMe);
        holder.body = (TextView)convertView.findViewById(R.id.tvBody);
        convertView.setTag(holder);
    }
    final Message message = getItem(position);
    final ViewHolder holder = (ViewHolder)convertView.getTag();
    final boolean isMe = message.getUserId() != null && message.getUserId().equals(mUserId);
    // Show-hide image based on the logged-in user.
    // Display the profile image to the right for our user, left for other users.
    if (isMe) {
        holder.imageMe.setVisibility(View.VISIBLE);
        holder.imageOther.setVisibility(View.GONE);
        holder.body.setGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
    } else {
        holder.imageOther.setVisibility(View.VISIBLE);
        holder.imageMe.setVisibility(View.GONE);
        holder.body.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
    }
    final ImageView profileView = isMe ? holder.imageMe : holder.imageOther;
    Picasso.with(getContext()).load(getProfileUrl(message.getUserId())).into(profileView);
    holder.body.setText(message.getBody());
    return convertView;
}

// Create a gravatar image based on the hash value obtained from userId
private static String getProfileUrl(final String userId) {
    String hex = "";
    try {
        final MessageDigest digest = MessageDigest.getInstance("MD5");
        final byte[] hash = digest.digest(userId.getBytes());
        final BigInteger bigInt = new BigInteger(hash);
        hex = bigInt.abs().toString(16);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "http://www.gravatar.com/avatar/" + hex + "?d=identicon";
}

final class ViewHolder {
    public ImageView imageOther;
    public ImageView imageMe;
    public TextView body;
}
}

这是一个与消息如何工作相关的活动类:

@ParseClassName("Message")
public class Message extends ParseObject {
public static final String USER_ID_KEY = "userId";
public static final String BODY_KEY = "body";

public String getUserId() {
    return getString(USER_ID_KEY);
}

public String getBody() {
    return getString(BODY_KEY);
}

public void setUserId(String userId) {
    put(USER_ID_KEY, userId);
}

public void setBody(String body) {
    put(BODY_KEY, body);
}
}

我不认为任何其他代码会被使用,但如果代码似乎被遗漏了,我将进行编辑。

我的错误说

  

com.parse.ParseObject无法强制转换为com.example.patri.parseapp.Message

我看了这个错误,没有任何解决方案可以在stackOverflow上运行。

编辑:Logcat

07-28 20:10:08.788 9922-9922 / com.example.patri.parseapp E / AndroidRuntime:FATAL EXCEPTION:main                                                                           处理:com.example.patri.parseapp,PID:9922

    java.lang.ClassCastException: com.parse.ParseObject cannot be cast to com.example.patri.parseapp.Message
                                                                              at com.example.patri.parseapp.ChatListAdapter.getView(ChatListAdapter.java:40)
                                                                              at android.widget.AbsListView.obtainView(AbsListView.java:2347)
                                                                              at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
                                                                              at android.widget.ListView.onMeasure(ListView.java:1182)
                                                                              at android.view.View.measure(View.java:17565)
                                                                              at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
                                                                              at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
                                                                              at android.view.View.measure(View.java:17565)
                                                                              at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5537)
                                                                              at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                                                                              at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
                                                                              at android.view.View.measure(View.java:17565)
                                                                              at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5537)
                                                                              at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:391)
                                                                              at android.view.View.measure(View.java:17565)
                                                                              at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5537)
                                                                              at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                                                                              at android.view.View.measure(View.java:17565)
                                                                              at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5537)
                                                                              at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
                                                                              at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
                                                                              at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
                                                                              at android.view.View.measure(View.java:17565)
                                                                              at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5537)
                                                                              at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                                                                              at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2615)
                                                                              at android.view.View.measure(View.java:17565)
                                                                              at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2045)
                                                                              at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1196)
                                                                              at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1409)
                                                                              at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1084)
                                                                              at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5990)
                                                                              at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
                                                                              at android.view.Choreographer.doCallbacks(Choreographer.java:580)
                                                                              at android.view.Choreographer.doFrame(Choreographer.java:550)
                                                                              at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
                                                                              at android.os.Handler.handleCallback(Handler.java:739)
                                                                              at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                              at android.os.Looper.loop(Looper.java:135)
                                                                              at android.app.ActivityThread.main(ActivityThread.java:5343)
                                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                                              at java.lang.reflect.Method.invoke(Method.java:372)
                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
07-28 20:10:10.729 9922-9922/com.example.patri.parseapp I/Process: Sending signal. PID: 9922 SIG: 9

1 个答案:

答案 0 :(得分:1)

总的来说,我不明白你为什么会收到这个错误。但是,正如注释中所解释的那样,所有Message对象都是ParseObject,但并不是所有的ParseObject都可以转换为Message,因此错误,但你没有强制转换,你的错误似乎在rule number, permit/deny, protocol, source IP, source port, des ip, des port. 1, permit, tcp, any, any, 10.1.2.230, 9091 2, permit, tcp, any, any, 10.1.2.241, pptp ,其中可能会发生隐式演员,但不应该因为你已经扩展final Message message = getItem(position)

以下是您可以尝试的一些事项。

使用对象类型

声明arraylist
ArrayAdapter<Message>

确保此处的此字符串是Parse表的名称

mMessages = new ArrayList<Message>();

实现适配器的@ParseClassName("Message") 方法。

getItem