gpt4 book ai didi

java - 如何从 AsyncTask 更新 View ?

转载 作者:行者123 更新时间:2023-11-30 05:09:35 25 4
gpt4 key购买 nike

我必须创建一个 RecyclerView,每次我的 AsyncTask 创建一个新项目时它都会更新。所以 RecyclerView 正在逐渐建立自己。每个 Item 都生成,然后 Thread hibernate 一段时间以查看进度较慢。

我尝试获取适配器并使用 notifyDataSetChanged() 更新它,但它不会像这样工作。我得到的错误是:

Only the original thread that created a view hierarchy can touch its views.

另一个想法是使用接口(interface)更新我的 MainActivity 中的适配器。但我不完全知道该怎么做。首先,我必须知道它是否是使用界面的正确方法,或者是否有更好的方法或者可能是一个非常简单的解决方案来解决我的问题。

public class MainActivity extends AppCompatActivity implements ListAdapter.Listener{

static RecyclerView recyclerView;

static ListAdapter adapter;

@Override
public void click(String name) {

if(getResources().getConfiguration().orientation== Configuration.ORIENTATION_LANDSCAPE){
DetailsFragment detailsFragment = (DetailsFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_details);
detailsFragment.setData(name);

}
else{
Toast.makeText(this, "clicked", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, DetailsActivity.class);
intent.putExtra("sorte_name", name);
startActivity(intent);
}
}


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerView();

new DataContainer().execute();

}

private void initRecyclerView(){
recyclerView = findViewById(R.id.meinRecyclerView);
adapter = new ListAdapter(this, DataContainer.meineSortenListe, this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}

}

public class DataContainer extends AsyncTask<Void, Void, Void> {

public static ArrayList<String> meineSortenListe = new ArrayList<String>();

ListAdapter myAdapter;

@Override
protected void onPreExecute() {
myAdapter =(ListAdapter)MainActivity.recyclerView.getAdapter();
super.onPreExecute();
}

@Override
protected Void doInBackground(Void... voids) {
for(int i= 0; i<50; i++){
meineSortenListe.add("Sorte "+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
onProgressUpdate();
}
Log.i("info", "array befüllt");
return null;
}

@Override
protected void onProgressUpdate(Void... values) {
myAdapter.notifyDataSetChanged();
super.onProgressUpdate(values);
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder>{

private ArrayList<String> mSorten;
private Context mContext;
private Listener listener;

public interface Listener{
void click(String name);
}


//Constructor
public ListAdapter(Context mContext, ArrayList<String> sortenListe, Listener listener) {
this.mContext = mContext;
this.mSorten = sortenListe;
this.listener=listener;
}

///////////////////////

public class ViewHolder extends RecyclerView.ViewHolder {

TextView sortenName;
LinearLayout sorteLayout;

public ViewHolder(View itemView) {
super(itemView);
sortenName = itemView.findViewById(R.id.nameSorte);
sorteLayout = itemView.findViewById(R.id.sorteLayout);
}

}


////////////////////////////////

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
holder.sortenName.setText(mSorten.get(position));

holder.sorteLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.click(mSorten.get(position));
}
});
}

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

}

最佳答案

在 Android 中,只有 UI 线程可以更新 View 。 (可以在 onPostExecute 中触发 UI 更新,因为 onPostExecute 正在切换到 UI 线程。)

由于您仍在 doInBackground() 函数中,因此您需要一个 Handler 将包含您的代码的 Runnable 发送到 UI 线程的 MessageQueue。

因此在您的 DataContainer 中,将 onProgressUpdate 更改为

protected void onProgressUpdate(Void... values) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable(){
public void run() {
myAdapter.notifyDataSetChanged();
}
});

super.onProgressUpdate(values);
}

关于java - 如何从 AsyncTask 更新 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53946513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com