Android - 使用fragement和asynctask

时间:2016-02-22 00:43:11

标签: java android android-asynctask

我正在尝试从托管的MySQL获取数据列表,然后在listview中返回结果。但是在使用碎片时我无法做到。

我收到以下错误:

  

com.example.test.myapp E / AndroidRuntime:FATAL EXCEPTION:AsyncTask#1                                                                                处理:com.exampletest.myapp,PID:31491                                                                                java.lang.RuntimeException:执行doInBackground()时发生错误                                                                                    在android.os.AsyncTask $ 3.done(AsyncTask.java:300)                                                                                    在java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)                                                                                    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)                                                                                    在java.util.concurrent.FutureTask.run(FutureTask.java:242)                                                                                    在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:231)                                                                                    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)                                                                                    at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587)                                                                                    在java.lang.Thread.run(Thread.java:818)                                                                                 引起:java.lang.ArrayIndexOutOfBoundsException:length = 1;索引= 1                                                                                    在com.example.test.myapp.homeOperation.doInBackground(homeOperation.java:71)                                                                                    在com.example.test.myapp.homeOperation.doInBackground(homeOperation.java:23)                                                                                    在android.os.AsyncTask $ 2.call(AsyncTask.java:288)                                                                                    在java.util.concurrent.FutureTask.run(FutureTask.java:237)                                                                                    在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:231)                                                                                    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)                                                                                    at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587)                                                                                    在java.lang.Thread.run(Thread.java:818)

使用下面显示的类:我连接到服务器,然后我获取结果,所以我可以解析数据并放入ArrayLists。

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

    List<String> title_list = new ArrayList<String>();
    List<String> id_list = new ArrayList<String>();

    Context context;
    AlertDialog alertDialog;

    homeOperation(Context ctx) {
        context = ctx;
    }

    @Override
    protected String doInBackground(String... params) {
        String type = params[0];
        String login_url = "http://xxxx/data.php";
        if (type.equals("home")) {
            try {
                String events = params[1];
                String task_owner = params[2];
                URL url = new URL(login_url);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                OutputStream outputStream = httpURLConnection.getOutputStream();
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                String post_data = URLEncoder.encode("events", "UTF-8") + "=" + URLEncoder.encode(events, "UTF-8") + "&"
                        + URLEncoder.encode("task_owner", "UTF-8") + "=" + URLEncoder.encode(task_owner, "UTF-8");
                bufferedWriter.write(post_data);
                bufferedWriter.flush();
                bufferedWriter.close();
                outputStream.close();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
                String result = "";
                String line = "";
                while ((line = bufferedReader.readLine()) != null) {
                    result += line;
                }
                bufferedReader.close();
                inputStream.close();
                httpURLConnection.disconnect();

                String[] arr = result.split("--");
                for (int i = 0; i < arr.length; i++) {
                    String cur = arr[i];
                    title_list.add(cur.split(":")[0]);
                    id_list.add(cur.split(":")[1]);
                }

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

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected void onPostExecute(String result) {
        Toast toast = Toast.makeText(this.context, result, Toast.LENGTH_LONG);
        toast.show();
    }

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

现在,这是我正在尝试从homeOperation类获取数据然后将数据放入ListView的类。

public class ContentFragment extends Fragment {

    ListView lv;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.content_fragment, container, false);

        lv = (ListView) view.findViewById(R.id.resultList);

        String type = "home";
        homeOperation homeOperation = new homeOperation(ContentFragment.this.getActivity());
        homeOperation.execute(type, "", "");


        // This is the array adapter, it takes the context of the activity as a
        // first parameter, the type of list view as a second parameter and your
        // array as a third parameter.
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity(), android.R.layout.simple_list_item_1, homeOperation.title_list);

        lv.setAdapter(arrayAdapter);


        //addButton onClick
        ImageButton addButton = (ImageButton) view.findViewById(R.id.addButton);
        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                addPaige(view);
            }
        });


        return view;
    }

    public void addPaige(View v) {
        Intent goToAddPaige = new Intent(getActivity(), AddPaige.class);
        startActivity(goToAddPaige);
    }
}

我认为使用片段发送上下文时会出现问题。

2 个答案:

答案 0 :(得分:1)

title_list将没有数据,因为AsyncTask.execute()将在lv.setAdapter(arrayAdapter);之后完成。

因此,如果您想要使用足够的数据处理title_list,请使用android.os.Handler中的onPostExecute()发送您的AsyncTask结果。

尝试如下:

您的AsyncTask

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

    List<String> title_list = new ArrayList<String>();
    List<String> id_list = new ArrayList<String>();

    Context context;
    Handler handler;
    AlertDialog alertDialog;

    homeOperation(Context ctx, Handler hnd) {
        context = ctx;
        handler = hnd;
    }

    @Override
    protected String doInBackground(String... params) {
        String type = params[0];
        String login_url = "http://xxxx/data.php";
        if (type.equals("home")) {
            try {
                String events = params[1];
                String task_owner = params[2];
                URL url = new URL(login_url);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                OutputStream outputStream = httpURLConnection.getOutputStream();
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                String post_data = URLEncoder.encode("events", "UTF-8") + "=" + URLEncoder.encode(events, "UTF-8") + "&"
                        + URLEncoder.encode("task_owner", "UTF-8") + "=" + URLEncoder.encode(task_owner, "UTF-8");
                bufferedWriter.write(post_data);
                bufferedWriter.flush();
                bufferedWriter.close();
                outputStream.close();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
                String result = "";
                String line = "";
                while ((line = bufferedReader.readLine()) != null) {
                    result += line;
                }
                bufferedReader.close();
                inputStream.close();
                httpURLConnection.disconnect();

                String[] arr = result.split("--");
                for (int i = 0; i < arr.length; i++) {
                    String cur = arr[i];
                    title_list.add(cur.split(":")[0]);
                    id_list.add(cur.split(":")[1]);
                }

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

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected void onPostExecute(String result) {
        Toast toast = Toast.makeText(this.context, result, Toast.LENGTH_LONG);
        toast.show();

        handler.sendEmptyMessage(0);
    }

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

您的片段

public class ContentFragment extends Fragment {

    ListView lv;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.content_fragment,container,false);

        lv = (ListView) view.findViewById(R.id.resultList);

        ViewHandler viewHnd = new ViewHandler(ContentFragment.this); // add this handler for parameter of yout AsyncTask.

        String type = "home";
        homeOperation homeOperation = new homeOperation(ContentFragment.this.getActivity(), viewHnd);
        homeOperation.execute(type, "", "");


        // This is the array adapter, it takes the context of the activity as a
        // first parameter, the type of list view as a second parameter and your
        // array as a third parameter.
//        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity() , android.R.layout.simple_list_item_1, homeOperation.title_list);
//
//        lv.setAdapter(arrayAdapter);

        //addButton onClick
        ImageButton addButton = (ImageButton) view.findViewById(R.id.addButton);
        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                addPaige(view);
            }
        });

        return view;
    }

    public void addPaige(View v){
        Intent goToAddPaige = new Intent(getActivity(), AddPaige.class);
        startActivity(goToAddPaige);
    }

    private static class ViewHandler extends Handler {
        private final WeakReference<ContentFragment> mFragment;

        ViewHandler(ContentFragment fragment) {
            mFragment = new WeakReference<ContentFragment>(fragment);
        }

        @Override
        public void handleMessage(Message msg) {
            ContentFragment fragment = mFragment.get();
            if (fragment != null) {
                fragment.handleMessage(msg);
            }
        }
    }

    private void handleMessage(Message msg) {
        if (msg.what == 0) {
            ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity() , android.R.layout.simple_list_item_1, homeOperation.title_list);

            lv.setAdapter(arrayAdapter);
        }
    }
}

答案 1 :(得分:0)

替换:

for (int i = 0; i < arr.length; i++) {
    String cur = arr[i];
    title_list.add(cur.split(":")[0]);
    id_list.add(cur.split(":")[1]);
}

使用:

for (int i = 0; i < arr.length; i++) {
    String cur = arr[i];
    String[] temp = cur.split(":");
    if (temp.length == 2){
        title_list.add(cur.split(":")[0]);
        id_list.add(cur.split(":")[1]);
    }
}

堆栈跟踪本身非常清晰:

java.lang.Thread.run(Thread.java:818) Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 at 

应转换为此行:

id_list.add(cur.split(":")[1]);

你不应该期望split method总会给你一定数量的子串。所以你必须写一个后备,当它没有。