从AsyncTask更新setListAdapter

时间:2015-08-30 19:05:03

标签: android android-listview android-listfragment

我正在使用此Tutorial及其sourcecodes在android中制作listview。我已经实现了使用本教程,但在更新setListAdapter期间,我无法动态更新listview。 我已经完成了许多stackoverflow问题,并且他们正在提供adapter.notifyDataSetChanged()作为解决方案。但我无法在AsyncTask中实现它。

ItemListFragment.java

public class ItemListFragment extends ListFragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = super.onCreateView(inflater, container, savedInstanceState);
    setListAdapter(new ItemAdapter(getActivity(), setArray(getActivity())));
    return v;
}

public ArrayList<Item> setArray(Context context)
{
    ArrayList<Item> items = new ArrayList<Item>();
    Realm realm = Realm.getInstance(context);
    RealmResults<Books> bs = realm.where(Books.class).findAll();
    for (int i = 0; i < bs.size(); i++) {
        Bitmap url = BitmapFactory.decodeFile(bs.get(i).getCover());
        String title = bs.get(i).getName();
        String description = bs.get(i).getAuthor();
        Item item = new Item(url, title, description);
        items.add(item);
    }
    realm.close();
    return items;
}
}

ItemAdapter.java

public class ItemAdapter extends ArrayAdapter<Item> {

public ItemAdapter(Context context, List<Item> items) {
    super(context, 0, items);
}

public View getView(int position, View convertView, ViewGroup parent)
{
    ItemView itemView = (ItemView) convertView;
    if (null == itemView)
    {
        itemView = ItemView.inflate(parent);
    }
    itemView.setItem(getItem(position));
    return itemView;
}
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list);
    if (BuildConfig.DEBUG)
        ViewServer.get(this).addWindow(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }
    else if (id == R.id.update) {
        Update update = new Update(getApplicationContext(), MainActivity.this);
        update.execute();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (BuildConfig.DEBUG)
        ViewServer.get(this).removeWindow(this);
}

@Override
protected void onResume() {
    super.onResume();
    if (BuildConfig.DEBUG)
        ViewServer.get(this).setFocusedWindow(this);
}
}

Update.java

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

private Context context;
public Activity activity;

 public Update(Context context, Activity activity)
{
    this.context = context;
    this.activity = activity;
}

    @Override
protected Void doInBackground(Void... params) {
    ServerAddress = context.getString(R.string.ServerAddress);
    StringExtras = context.getString(R.string.CheckBook);
    Realm realm = null;
    try {
        URL url = new URL(ServerAddress + StringExtras);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setRequestMethod("GET");
        httpURLConnection.setRequestProperty("Content-length", "0");
        httpURLConnection.setUseCaches(false);
        httpURLConnection.setAllowUserInteraction(false);
        httpURLConnection.setConnectTimeout(1000);
        httpURLConnection.setReadTimeout(1000);
        httpURLConnection.connect();

        int responseCode = httpURLConnection.getResponseCode();
        Log.i("Response Code",responseCode+"");

        BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
        String InputLine;
        StringBuilder response = new StringBuilder();

        while ((InputLine = br.readLine()) != null)
        {
            response.append(InputLine);
        }
        br.close();
        httpURLConnection.disconnect();

        Log.i("Response Data", response.toString());

        GsonBuilder gsonBuilder = new GsonBuilder();
        Gson gson = gsonBuilder.create();

        JSONArray array = new JSONArray(response.toString());
        //booksList = Arrays.asList(books);
        //JSONArray jsonArray = object.getJSONArray("cover");

        realm = Realm.getInstance(context);
        for (int i=0; i< array.length(); i++ ) {
            JSONObject object = array.getJSONObject(i);
            Books books = gson.fromJson(object.toString(), Books.class);
            Publish(books, realm);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        if (realm != null){
            realm.close();
        }
    }
    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    //i want to call the setarray that contains my database data which has been updated on `doinbackground` and update the listview accordingly.
//The below codes are just the codes that i have tried but what should i do to update the listview.
activity.runOnUiThread(new Runnable() {
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public void run() {
            ItemListFragment activity1 = new ItemListFragment();
            ArrayList<Item> arrayList = activity1.setArray(context);
            List<Item> list = new ArrayList<Item>();
            int i = 0;
            for (Item item : arrayList)
            {
                list.add(arrayList.get(i));
                i++;
            }
            activity1.arrayAdapter.addAll(list);
            activity1.arrayAdapter.notifyDataSetChanged();
        }
    });

   }

我正在尝试从postexcution更新列表视图。那么,我如何通过它更新视图。

来自AsyncTask的

错误

只是因为你需要,但这不是问题

8-30 16:31:47.976    1167-1167/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
        at np.com.thefourthgeneration.Update$1.run(Update.java:124)
        at android.app.Activity.runOnUiThread(Activity.java:4673)
        at np.com.thefourthgeneration.Update.onPostExecute(Update.java:108)
        at np.com.thefourthgeneration.Update.onPostExecute(Update.java:34)
        at android.os.AsyncTask.finish(AsyncTask.java:631)
        at android.os.AsyncTask.access$600(AsyncTask.java:177)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

<强>布局/ activity_list

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

<强>布局/ list_fragment

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

<强> MainActivity

public class MainActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);

        FragmentManager fm = getFragmentManager();

        itemListFragment = (ItemListFragment) fm.findFragmentByTag(ItemListFragment.class.getSimpleName());
        if (itemListFragment == null) {
            itemListFragment = new ItemListFragment();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();
            fragmentTransaction.replace(R.id.content_frame, itemListFragment, ItemListFragment.class.getSimpleName());
            fragmentTransaction.commit();
        }
        if (BuildConfig.DEBUG) {
            ViewServer.get(this).addWindow(this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (BuildConfig.DEBUG) {
            ViewServer.get(this).removeWindow(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (BuildConfig.DEBUG) {
            ViewServer.get(this).setFocusedWindow(this);
        }
    }
}

<强> ItemListFragment

public class ItemListFragment extends Fragment
{
    private ListView listView;
    private ItemAdapter itemAdapter;
    private ArrayList<Item> itemArrayList = new ArrayList<>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.list_fragment, container, false);
        itemAdapter = new ItemAdapter(getActivity(), itemArrayList);
        listView = (ListView) view.findViewById(R.id.listView);
        listView.setAdapter(itemAdapter);
        return view;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_main, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:
                return true;
            case R.id.update:
                new Update(getActivity()).execute();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }

    }

    public class Update extends AsyncTask<Void, Void, Void>
    {
        private Context context;

        public Update(Context context) {
            this.context = context;
        }

        @Override
        protected Void doInBackground(Void... params) {
            ServerAddress = context.getString(R.string.ServerAddress);
            StringExtras = context.getString(R.string.CheckBook);
            Realm realm = null;
            try {
                URL url = new URL(ServerAddress + StringExtras);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setRequestProperty("Content-length", "0");
                httpURLConnection.setUseCaches(false);
                httpURLConnection.setAllowUserInteraction(false);
                httpURLConnection.setConnectTimeout(1000);
                httpURLConnection.setReadTimeout(1000);
                httpURLConnection.connect();

                int responseCode = httpURLConnection.getResponseCode();
                Log.i("Response Code", responseCode + "");

                BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
                String InputLine;
                StringBuilder response = new StringBuilder();

                while ((InputLine = br.readLine()) != null) {
                    response.append(InputLine);
                }
                br.close();
                httpURLConnection.disconnect();

                Log.i("Response Data", response.toString());

                GsonBuilder gsonBuilder = new GsonBuilder();
                Gson gson = gsonBuilder.create();

                JSONArray array = new JSONArray(response.toString());
                //booksList = Arrays.asList(books);
                //JSONArray jsonArray = object.getJSONArray("cover");

                realm = Realm.getInstance(context);
                for (int i = 0; i < array.length(); i++) {
                    JSONObject object = array.getJSONObject(i);
                    Books books = gson.fromJson(object.toString(), Books.class);
                    Publish(books, realm);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (realm != null) {
                    realm.close();
                }
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            itemArrayList.clear();
            itemArrayList.addAll(getArray(context));
            itemAdapter.notifyDataSetChanged();
        }

        public ArrayList<Item> getArray(Context context) {
            ArrayList<Item> items = new ArrayList<Item>();
            Realm realm = Realm.getInstance(context);
            RealmResults<Books> bs = realm.where(Books.class).findAll();
            for (int i = 0; i < bs.size(); i++) {
                Bitmap url = BitmapFactory.decodeFile(bs.get(i).getCover());
                String title = bs.get(i).getName();
                String description = bs.get(i).getAuthor();
                Item item = new Item(url, title, description);
                items.add(item);
            }
            realm.close();
            return items;
        }

    }

    public class ItemAdapter extends ArrayAdapter<Item>
    {

        public ItemAdapter(Context context, List<Item> items) {
            super(context, 0, items);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ItemView itemView = (ItemView) convertView;
            if (null == itemView) {
                itemView = ItemView.inflate(parent);
            }
            itemView.setItem(getItem(position));
            return itemView;
        }
    }
}

它不是100%的工作代码,因为我不完全理解所有结构(如Realm),我不测试它,但它是主要的想法。