2015-12-17 302 views
0

我有一个片段类,描述RecyclerView。创建元素需要arrayarray通过解析JSON而形成。当我使用良好的互联网连接时,一切正常,并且我可以看到理想的项目列表。但使用低速连接我的UI是空的。同步线程

我意识到threads存在一些问题,但我没有足够的知识来解决我的问题。

下面是一个代码:

public class ListVideo extends Fragment { 
private int loadLimit = 9; 
private RecyclerView recyclerView; 
private RecyclerAdapter adapter; 
private LinearLayoutManager linearLayoutManager; 
final OkHttpClient client = new OkHttpClient(); 
List<VideoData> videoList; 
List<String> videoDataList; 
JSONArray json_array_list_of_videos; 
int counter = 0; 
int offset; 

@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 
         @Nullable Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.listvideofragment, container, false); 
} 

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    videoList = new ArrayList<>(); 
    videoDataList = new ArrayList<>(); 
    recyclerView = (RecyclerView) view.findViewById(R.id.list); 

    loadData(offset); 
    createRecycleView(); 
    recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(
      linearLayoutManager) { 
     @Override 
     public void onLoadMore(int offset) { 
      // do somthing... 

      loadMoreData(offset); 

     } 

    }); 


} 

private void loadMoreData(int offset) { 

    loadLimit += 10; 
    loadData(offset); 

    adapter.notifyDataSetChanged(); 

} 

private void loadData(final int offset) { 
    try { 
     Request request = new Request.Builder() 
       .url("http://video.motti.be/api/video.getVideoList?offset=" + 
         offset 
         + "&limit=20") 
       .build(); 

     client.newCall(request).enqueue(new Callback() { 
      @Override 
      public void onFailure(Request request, IOException throwable) { 
       throwable.printStackTrace(); 
      } 

      @Override 
      public void onResponse(Response response) throws IOException { 
       try { 
        if (!response.isSuccessful()) 
         throw new IOException("Unexpected code " + response); 

        Headers responseHeaders = response.headers(); 
        for (int i = 0; i < responseHeaders.size(); i++) { 
         System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); 
        } 

        String json_string_obj = response.body().string(); 
        JSONObject url = new JSONObject(json_string_obj); 
        json_array_list_of_videos = url.getJSONArray("data"); 
        System.out.println(json_array_list_of_videos.toString()); 
        for (int y = 0; y <= 9; y++) { 
         if (json_array_list_of_videos.get(y).toString().equals("A9knX0GXrg")) { 
          videoDataList.add("6kS9Tt1e47g"); 
         } else { 
          videoDataList.add(json_array_list_of_videos.get(y).toString()); 
          System.out.println("++++++" + json_array_list_of_videos.get(y).toString()); 
         } 
        } 
        for (int i = counter; i <= loadLimit; i++) { 
         if (videoDataList == null) { 
          return; 
         } else { 
          VideoData next_queue_id = new VideoData(videoDataList.get(i)); 
          videoList.add(next_queue_id); 
          counter++; 

         } 
        } 


       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

      } 
     }); 

    } catch (ArrayIndexOutOfBoundsException e) { 
     e.printStackTrace(); 

    } 

} 

public void createRecycleView() { 

    adapter = new RecyclerAdapter(videoList, getContext()); 
    linearLayoutManager = new LinearLayoutManager(getActivity()); 
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    recyclerView.setHasFixedSize(true); 
    recyclerView.setLayoutManager(linearLayoutManager); 
    recyclerView.setAdapter(adapter); 
} 
} 

我明白了,我得到Response后即可new adapter creates.For知识的缺乏,因为我悲伤,我不知道如何使threadonResponse方法等待。

希望你不会觉得这个问题太沉闷或愚蠢,并会帮助我。

预先感谢您!

回答

0

您需要在修改其列表(videoList)后通知适配器。

目前loadMoreData(int offset)方法不能保证,因为loadData(offset);方法可以在列表被修改之前返回(请求被异步处理)。

你可以做的是这样的:

loadMoreData(int offset)方法取出adapter.notifyDataSetChanged();语句,并把它添加到onResponse(Response response)方法。

实施例:

@Override 
public void onResponse(Response response) throws IOException { 
    try { 
     ... 
     for (int i = counter; i <= loadLimit; i++) { 
      if (videoDataList == null) { 
       return; 
      } else { 
       VideoData next_queue_id = new VideoData(videoDataList.get(i)); 
       videoList.add(next_queue_id); 
       counter++; 
      } 
     } 
     ListVideo.this.runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       adapter.notifyDataSetChanged(); 
      } 
     }); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

这种方法可以产生其他问题,因为videoList可由多个线程同时进行修改。您需要找到一种方法来同步访问此列表或使用线程安全列表。

+0

非常感谢,@Titus! 'runOnUiThread'出现了一些问题,所以我使用了'new Handler(Looper.getMainLooper())',它解决了!再次感谢你! –

+0

@PeterParker我很高兴我能帮上忙,祝你好运。 – Titus