0

나는 응용 프로그램에 대한 채팅 기능을 만들고있어 매우 잘 작동합니다. 그러나 나는 메시지가 전송되었거나 여전히 서버의 응답을 기다리고 있다고 사용자에게 보여주고 싶습니다.AsyncTask doInBackground를 수행 한 후 recyclerview에서 항목을 업데이트하는 방법은 무엇입니까?

분야 :

List<ChatMessage> chatMessages; 
ChatAdapter chatAdapter; 
RecyclerView chatRecyclerView; 
ImageButton submitMessageBtn; 

이 내 ChatActivity 클래스에 메시지를 보내는 방법 :

public void submitMessage(final String messageType, final byte[] message){ 
    final ChatMessageResponse messageObject = new ChatMessageResponse(); 
    new AsyncTask<Void, Void, Void>() { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      messageObject.setMessage(message); 
      messageObject.setYours(true); 
      messageObject.setUserNickname(getNickname()); 
      messageObject.setCreationDate(DateTime.now().withZone(DateTimeZone.UTC)); 
      messageObject.setType(messageType); 

      AddMessage(messageObject); 
     } 


     @Override 
     protected Void doInBackground(Void... voids) { 
      try { 

       chatClient.chat().sendMessage(eventId, messageType, message); 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         // Update message on the list after has been sent to server 
        } 
       }); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     return null; 
     } 
    }.execute(); 

} 

public void AddMessage(ChatMessage message) 
    { 
     chatMessages.add(message); 
     chatAdapter.notifyDataSetChanged(); 
     chatRecyclerView.scrollToPosition(chatMessages.size() -1); 
    } 

When message is immediatly added to the adapter it should look like this: 내 ChatAdapter 클래스는 다음과 같이 설정입니다 :

  public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> { 

      private static final int VIEW_TYPE_MESSAGE_THIS_USER = 0; 
      private static final int VIEW_TYPE_MESSAGE_OTHER_USER = 1; 
      private final Activity activity; 
      public List<ChatMessage> chats=new ArrayList<>(); 
      ArrayList<String> usercolor=new ArrayList<>(); 
      Context mContext; 
      View view; 

    public ChatAdapter(List<ChatMessage> chats, Context mContext, Activity activity) { 
       this.chats = chats; 
       this.mContext = mContext; 
       this.activity = activity; 
      } 

      @Override 
      public ChatViewHolder onCreateViewHolder(ViewGroup parent, int viewType){ 
       mContext = parent.getContext(); 

       if (viewType == VIEW_TYPE_MESSAGE_OTHER_USER) { 
        view = View.inflate(mContext, R.layout.message_item_left, null); 
       } else if (viewType == VIEW_TYPE_MESSAGE_THIS_USER){ 
        view = View.inflate(mContext, R.layout.message_item, null); 
       } 

       return new ChatViewHolder(view,(View.OnLongClickListener)activity); 
      } 

     @Override 
     public void onBindViewHolder(final ChatViewHolder holder, int position){ 
      final ChatMessageResponse m = (ChatMessageResponse) chats.get(position); 
      if (getItemViewType(position) == VIEW_TYPE_MESSAGE_OTHER_USER){ 
       holder.bindToView1(m); 
      } else if (getItemViewType(position) == VIEW_TYPE_MESSAGE_THIS_USER) 
      { 
       holder.bindToView(m); 
      } 
     } 

     @Override 
     public int getItemCount() { 
      return chats.size(); 
     } 

     @Override 
     public int getItemViewType(int position) { 
      return chats.get(position).isYours() ? VIEW_TYPE_MESSAGE_THIS_USER : VIEW_TYPE_MESSAGE_OTHER_USER; 
      } 

    } 

When the server's response is positive the views in the ChatViewHolder (that I don't show the code because is too long) should change visibility state 누군가가보기에 대한 의견을 받고 해당 활동의 asynctask에서 변경하거나 내 어댑터의 콜백 수신기를 만들라고했습니다.

하지만 아무런 도움이되지 않는 방법 중 하나를 수행하는 방법에 대해 감사드립니다.

+0

doInBackground()가 완료된 후에 UI 스레드의 변경 사항을 처리하려면 onPostExecute()를 구현해야합니다. – Carnal

+0

@Carnal은별로 도움이되지 않습니다. 나는 이미 runOnUiThread()를 가지고있다. –

+0

runOnUiThread는 AsyncTask가 호출되면 아무런 의미가 없다. doInBackground는 백그라운드에서 실행된다. onPostExecute 구현을 추가하면 문제가 해결됩니다. –

답변

0

"콜백"또는 "인터페이스"를 잘 알고 있습니까? 인터페이스를 작성하여 활동에 구현할 수 있습니다. "AsyncTask"의 매개 변수로 콜백을 전달하고 거기에서 사용하십시오. 활동에

//Interface class 
/** 
* Created by gmora 
*/ 
public interface IProcess { 

    void updateAdapter(String result); 
} 

: AsyncTask를에 마지막으로

public class YourActivity extends AppCompatActivity { 

    private IProcess mProcess; 
    private Adapter mRecyclerAdapter; 
    private RecyclerView mRecyclerView; 
    private List<ChatMessage> chats; //update chats on activity and refresh your adapter 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_layout); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     mProcess = new IProceso() { 
       @Override 
       public void updateAdapter(String pException) { 
        //update chats ... and update mAdater.notifyDataChange()... 
        // or mRecyclerView.setAdapter(new Adpater.... with new list chats).. 
       } 
      }; 

     mRecyclerView = find.... 
     // etc.... 
     mRecyclerAdapter = new RecyclerAdapter(chats, ...); 
     mRecyclerView.setAdapter(mRecyclerAdapter); 
    } 
} 

이 ... AsyncTask를 바랍니다에서 외부 클래스를 만들!

/** 
* Created by gmora. 
*/ 

public class YourAsyncTaskClass extends AsyncTask<String, Void, String > { 

    private IProcess iProcess; 

    public StarSearchPrinterTask(IProcess pIProcess) { 
     this.iProcess= pIProcess; 
    } 

    @Override 
    protected void onPreExecute() { 
     //loading... its optional 
    } 

    @Override 
    protected String doInBackground(String... interfaceType) { 
     // execute webservice or api and get results.. 

     return results; 
    } 

    @Override 
    protected void onPostExecute(String results) { 
     mIProceso.updateAdapter(results); 
    } 
} 
관련 문제