我正在学习如何使用parse创建聊天客户端的教程。链接:https://github.com/codepath/android_guides/wiki/Building-Simple-Chat-Client-with-Parse当我在应用程序中按下发送时,它会说“parseapp”已经停止。我是一名新程序员,不确定为什么它不起作用。我的代码中没有错误。尽管这一定与按下按钮的时间有关,或者有一些变量没有被使用。请帮忙!事先谢谢。
这是我认为最有可能出现问题的主要行为代码:
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);
}
}
我不认为任何其他代码会有用,但如果代码似乎被遗漏,我会进行编辑。
我的错误是
通用域名格式。作语法分析无法将ParseObject强制转换为com。实例帕特里。parseapp。消息
我查过这个错误,没有一个解决方案对stackOverflow有效。
编辑:Logcat
07-28 20:10:08.788 9922-9922/com。实例帕特里。parseapp E/AndroidRuntime:致命异常:主进程:com。实例帕特里。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
总的来说,我不明白你为什么会犯这样的错误。但是,正如注释中所解释的,所有消息对象都是ParseObject,但并非所有ParseObject都可以转换为消息,因此会出现错误,但您没有转换,并且您的错误似乎出现在final Message Message=getItem(position)
,其中可能会发生隐式转换,但不应该发生,因为您扩展了ArrayAdapter
这里有一些你可以尝试的事情。
用对象类型声明arraylist
mMessages = new ArrayList<Message>();
确保这里的字符串是解析表的名称
@ParseClassName("Message")
实现适配器的
getItem
方法。
public class ChatListAdapter extends ArrayAdapter<Message> {
private String mUserId;
private ArrayList<Message> messages;
public ChatListAdapter(Context context, String userId, ArrayList<Message> messages) {
super(context, 0, messages);
this.mUserId = userId;
this.messages = messages;
}
@Override
public Message getItem(int position) {
return messages.get(position);
}
在logcat我看到了这个- 需要关于发生了什么以及如何解决的建议。我使用的是android studio北极狐2020.3.1补丁3。
当用户在我的通知中单击一个按钮时,我正试图打开,而该应用程序仅在后台运行并提供服务。单击按钮时,这些行在类中被触发: 我已经检查过了,这些行被触发了,所以对按钮的点击做出反应没有问题,但是不会打开。 有什么建议吗?为什么这对我不起作用,我怎么能让它起作用? 我被要求提供更多的代码,因此在我的
问题内容: 我一直试图在Eclipse中制作我的第一个android应用程序(一个简单的温度转换器),但是当我单击手机上的按钮时,该应用程序崩溃了。这是完整的Java代码 单击按钮时的LogCat 最后是按钮的xml 我不确定如何解决此问题,因此希望有人可以提供帮助。谢谢。 问题答案: 首先初始化您的按钮,然后将onclicklistener设置为它们 同样设置另一个按钮
我对python有点陌生,这是我第一次使用套接字,我试图制作一个具有客户端和服务器的应用程序,用户可以在客户端中输入,它将被发送到服务器,然后将其发送给所有其他客户端。我已经将其设置为工作状态,但每当我尝试发送第二条消息时,我总是收到一个错误错误:[Errno 10058]发送或接收数据的请求被禁止,因为套接字已经在之前的关闭调用中关闭了该方向。我如何才能做到这一点? 尝试在启动新套接字或发送新消
每次我点击按钮1,我的应用程序就会崩溃。同一活动中的另一个按钮可以正常工作。我已经试过更换按钮和代码了。控制台中没有错误。
这是崩溃错误logcat,每次我时钟在我的寄存器btn应用程序崩溃。 我的模拟器是在Android模拟器设备上的2gb ram。 2019-09-22 16:36:39.307 6454-6454/com。康奈克斯。connexsocial E/AndroidRuntime:致命异常:主进程:com。康奈克斯。connexsocial,PID:6454Android系统。所容纳之物Activity