Issue
In my project, I am trying to scraped data. I have prepopulated sqlite database in my asset folder. The adapter class MySqliteAdapter.java fetch the sqlite database which contains a list of artitle titles and their links.
These article titiles and links is then fetched and add into an ArrayList on onBindViewHolder
method. Then I implemented a jsoup class to scraped the articles data by looping the article links that are stored in the ArrayList. The scraped articles data is then inserted into the firebase database.
However, while it works, but the problem is that for loops somehow seems to loop twice. For instance if the arraylist.size is 2, data is inserted into the database twice.
Below is my code.
**MySqliteAdapter.java**
public MySqliteAdapter(Activity activity, List<String> data)
{
this.data = data;
this.activity = activity;
}
// This method is used to attach
// custom layout to the recycler view
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
LayoutInflater LI = activity.getLayoutInflater();
View vw = LI.inflate(R.layout.custom_layout, null);
mainActivity = new MainActivity();
return new ViewHolder(vw);
}
// This method is used to set the action
// to the widgets of our custom layout.
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
{
holder.linksURL.setText(data.get(position));
list.add(data.get(position));
url = holder.linksURL.getText().toString();
new doIT().execute();
}
@Override
public int getItemCount()
{
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView linksURL;
public ViewHolder(View itemView)
{
super(itemView);
this.linksURL = itemView.findViewById(R.id.textView);
}
}
public class doIT extends AsyncTask<Void,Void,Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
try
{
for(int i=0; i<2; i++)
{
Document document = Jsoup.connect(list.get(i).toString()).get(); //Fetch the link from firebase to solved broken link
org.jsoup.select.Elements elements_Title = document.getElementsByClass("wp-block-post-title");
org.jsoup.select.Elements elements_Text = document.getElementsByClass("has-global-padding is-layout-constrained entry-content wp-block-post-content");
str_Title = elements_Title.html();
str_Text = elements_Text.html();
insertData();
}
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid)
{
super.onPostExecute(aVoid);
}
}
//End of Jsoup Scrapping Website
private void insertData()
{
scraped_title = str_Title;
scraped_text = str_Text;
Map<String, Object> map = new HashMap<>();
map.put("title", scraped_title);
map.put("lyrics", scraped_text);
FirebaseDatabase.getInstance().getReference().child("worshipintercessor").push()
.setValue(map)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void unused) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
//Toast.makeText(MainActivity.this, "Error!", Toast.LENGTH_LONG).show();
}
});
}
Solution
The only thing you should be doing in onBindViewAdapter
is rendering your data in the view. You should not be saving anything to a database or making requests or any other thing that causes side effects.
The reason it is getting called twice is because onBindViewHolder
is called at least once for each item in your list that appears on the screen. Remove new doIT().execute();
from onBindViewHolder
and instead, call it in a place where you can be sure it will only get called once.
Answered By - Leo Aso
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.