我正在开发一个Android应用程序,实际上是一个消息传递应用程序。
我正在使用RecyclerView
呈现特定会话的内容。
我坚持的是,我有一个片段,它从用户那里获取输入以创建一个新对话,我使用该信息为该对话启动一个活动,更新其布局,为RecyclerView等适配器。 / p>
当用户输入有效(非空等)时,我会关闭该片段,在对话中发送测试消息并使用对话标识符开始对话活动。
但是我得到的这个NullPointerException
与RecyclerView
有关,堆栈跟踪的标题是:
java.lang.NullPointerException:尝试调用虚方法'boolean android.support.v7.widget.RecyclerView $ LayoutManager.onAddFocusables(android.support.v7.widget.RecyclerView,java.util.ArrayList,int,int) '在空对象引用上
在此之上,我还得到一个说No adapter attached; skipping layout
。
我在stackoverflow上看到了这里的答案,你应该首先发起Adapter/LayoutManager
,然后将它附加到RecyclerView,但我已经在做了。
我正在写这些代码的片段。
当用户输入有效时调用的接口方法。
public void onCreateConversation(DialogFragment dialog, String conversationName) {
dialog.dismiss();
Conversation newConversation = client.newConversation(Arrays.asList(userList);
String identifier = newConversation.getId().toString();
// prepare initiation message
String initialMessageText = "starting conversation";
MessagePart initialMessagePart = client.newMessagePart("text/initiation", initialMessageText.getBytes());
Message initialMessage = client.newMessage(Arrays.asList(initialMessagePart));
// send initiation message
newConversation.send(initialMessage);
startConversationActivity(identifier);
}
开始对话活动
public void startConversationActivity(String identifier) {
Intent intent = new Intent(this, ChatConversationActivity.class);
intent.putExtra("IDENTIFIER", identifier);
startActivity(intent);
}
ChatConversationActivity的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loading_conversation);
Intent intent = getIntent();
conversationIdentifier = intent.getStringExtra("IDENTIFIER");
// argument 'client' is reference to the connection
conversationViewControl = new ConversationViewController(this, client, conversationIdentifier);
}
在ConversationViewController的构造函数
中
public ConversationViewController(ChatConversationActivity activity, Client client, String identifier) {
activity.setContentView(R.layout.activity_conversation);
// messages recycler view
messageRecyclerView = (RecyclerView) activity.findViewById(R.id.messageRecyclerView);
// layout manager for recycler view
recyclerViewLayoutManager = new LinearLayoutManager(activity);
// message adapter
MessageAdapter = null;
// private conversation object in ConversationViewController
activeConversation = getConversation(identifier);
// this will render the layout for conversation
drawConversationView(activeConversation);
}
'getConversation'要求服务与标识符进行对话
private Conversation getConversation(String identifier) {
if(activeConversation == null) {
Query query = Query.builder(Conversation.class)
.predicate(new Predicate(Conversation.Property.ID, Predicate.Operator.EQUAL_TO, identifier))
.build();
List<Conversation> results = client.executeQuery(query, Query.ResultType.OBJECTS);
if(results != null && results.size() > 0) {
// loading first object as identifiers are unique for all conversations
return results.get(0);
}
}
return activeConversation;
}
'drawConversationView'将更新会话视图
private void drawConversation(Conversation conversation) {
// Only proceed if there is a valid conversation
if(conversation != null) {
Log.d("create conversation", "activeConversation is not null");
// recycler view layout manager
recyclerViewLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
messageRecyclerView.setLayoutManager(recyclerViewLayoutManager);
// messages for the conversation
List<Message> messages = client.getMessages(conversation);
// recycler view adapter, 'activity' is also private object
messageAdapter = new MessageAdapter(messages, activity);
messageRecyclerView.setAdapter(messageAdapter);
} else {
Log.d("create conversation", "activeConversation is still null");
}
}
此事件崩溃randomly
,有时会创建对话,我会看到它的视图,有时不会。
我是Java和Android世界的新手,你能帮我跟踪一下吗?
答案 0 :(得分:1)
我可以在你的代码中看到两个不合理的东西。
收集对RecyclerView的引用
后,立即附加LayoutManager
在您尝试收集对话数据之前,您可以尝试在LayoutManager
本身附加RecyclerView
至ConversationViewController
。
...
// messages recycler view
messageRecyclerView = (RecyclerView) mca.findViewById(R.id.messageRecyclerView);
// layout manager for recycler view
recyclerViewLayoutManager = new LinearLayoutManager(mca);
recyclerViewLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// set this right here
messageRecyclerView.setLayoutManager(recyclerViewLayoutManager);
...
这可能会让你免于崩溃。
实施回调以确保仅在拥有数据时进行渲染
在ConversationViewController
中,您一个接一个地调用getConversation
和drawConversation
方法,但是您在第一个方法中收集一些数据并在第二个方法中使用它。
您可以尝试实现一个接口,并在您拥有会话数据后使用该方法从方法drawConversation
调用getConversation
,而不是同步调用它们。
我希望这会对你有所帮助。