- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个 android 应用程序,它实际上是一个消息传递应用程序。
我正在使用 RecyclerView
来呈现特定对话的内容。
我坚持的是,我有一个 fragment ,它从用户那里获取输入来创建一个新的对话,我使用该信息来启动该对话的 Activity ,更新其布局,RecyclerView 的适配器等。
我在用户输入有效(非空等)时关闭 fragment ,在对话中发送测试消息并使用对话标识符启动对话 Activity 。
但是我得到了与 RecyclerView
相关的 NullPointerException
,堆栈跟踪的标题是:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$LayoutManager.onAddFocusables(android.support.v7.widget.RecyclerView, java.util.ArrayList, int, int)' on a null object reference
在此之上,我还听到一句话 No adapter attached;跳过布局
。
我在 stackoverflow 上看到的答案是,您应该先启动一个 Adapter/LayoutManager
,然后将其附加到 RecyclerView,但我已经在这样做了。
我在这里写我的代码 fragment 。
Interface method that gets invoked when user input is valid.
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);
}
Start an activity for the conversation
public void startConversationActivity(String identifier) {
Intent intent = new Intent(this, ChatConversationActivity.class);
intent.putExtra("IDENTIFIER", identifier);
startActivity(intent);
}
The onCreate method of ChatConversationActivity
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);
}
In the constructor of 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' asks the service for conversation with an identifier
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' will update the view for conversation
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");
}
}
这东西随机
崩溃,有时会创建对话,我可以看到它的 View ,有时却看不到。
我是 Java 和 Android 领域的新手,你能帮我跟踪一下吗?
最佳答案
我可以在您的代码中看到两个不合理的地方。
Attach the LayoutManager as soon as you collect a reference to RecyclerView
您可以尝试在 ConversationViewController
本身中将 LayoutManager
附加到 RecyclerView
,然后再尝试收集对话数据。
...
// 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);
...
这可能会使您免于崩溃。
Implement callbacks to make sure you render only when you have the data
在 ConversationViewController
中,您依次调用了 getConversation
和 drawConversation
方法,但是您首先收集了一些数据并使用第二种方法。
您可以尝试实现一个接口(interface),并使用它从方法 getConversation
中调用 drawConversation
,一旦您拥有对话数据,而不是同步调用它们。
希望本文对您有所帮助。
关于java - 为什么我的 android Activity 偶尔会崩溃并显示 "No adapter attached; skipping layout"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31276294/
我是一名优秀的程序员,十分优秀!