Android解析xml和AsyncTask doInBackground方法永远不会完成

时间:2015-07-31 08:58:46

标签: android xml parsing android-asynctask bluetooth

我是Android开发的新手,我构建了一个简单的应用程序,通过蓝牙从我的计算机接收xml文件。现在我想解析xml个文件,我希望在AsyncTask doInBackground方法中执行此操作。首先,我将字节写入xml文件

private void writeBytesToOutputStream(byte[] bytes, String path) {

        File file = new File(path);
        OutputStream out;
        try {
            if(file.exists()){
                file.delete();
            }
            file.createNewFile();

            out = new FileOutputStream(file);
            out.write(bytes);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // method that sets file and later calls execute().
        xml.setFile(file);
    }

这是我内心的AsyncTask类。

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

        private XmlPullParserFactory xmlFactoryObject;
        private XmlPullParser myParser;
        private File file;

        String value;

        public XmlParser() {
            try {
                xmlFactoryObject = XmlPullParserFactory.newInstance();
                myParser = xmlFactoryObject.newPullParser();

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

        public void setFile(File file1) {
            file = file1;
            execute();
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            FileInputStream fis = null;
            try {
                if(file == null){
                    Toast.makeText(getActivity(), "NULL", Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(getActivity(), "NOT NULL " + file.getName(), Toast.LENGTH_LONG).show();
                    fis = new FileInputStream(file);
                    myParser.setInput(fis, null);
                    fis.close();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected String doInBackground(Void... params) {
            int event;
            try {
                event = myParser.getEventType();

                while (event != XmlPullParser.END_DOCUMENT) {
                    String name = myParser.getName();
                    switch (event) {
                        case XmlPullParser.START_TAG:

                            break;

                        case XmlPullParser.END_TAG:

                            if (name.equals("from")) {
                                value = myParser.getAttributeValue(null, "value");
                                System.out.println("JUST FOR TEST " + value);
                                event = XmlPullParser.END_DOCUMENT;
                            }
                            break;

                        default:
                            break;
                    }
                    try {
                        event = myParser.next();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }catch (XmlPullParserException e) {
                e.printStackTrace();
            }
            return value;
        }

        @Override
        protected void onPostExecute(String aVoid) {
            super.onPostExecute(aVoid);
            System.out.println("myEND " + aVoid);
            Toast.makeText(getActivity(), "THE END!!! " + aVoid, Toast.LENGTH_LONG).show();
        }
    }

某种方法doInBackground()永远不会完成。我花了差不多四个小时试图解决它,但我找不到什么是错的。我还添加了我的完整代码

public class UiFragment extends Fragment {

    private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
    private static final int REQUEST_ENABLE_BT = 3;

    private String deviceName = null;

    private BluetoothAdapter adapter = null;

    //private ListView listViewConversation;
    //private ArrayAdapter<String> conversationAdapter;

    private Button onButton, offButton;

    private BluetoothConnection connection = null;

    ImageView im;

    private XmlParser xml;

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

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        //listViewConversation = (ListView) view.findViewById(R.id.in);
        onButton = (Button) view.findViewById(R.id.onButton);
        offButton = (Button) view.findViewById(R.id.offButton);

        im = (ImageView) view.findViewById(R.id.imageView);
    }

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

        adapter = BluetoothAdapter.getDefaultAdapter();
        xml = new XmlParser();

        // If the adapter is null, then Bluetooth is not supported
        if (adapter == null) {
            FragmentActivity activity = getActivity();
            Toast.makeText(activity, "Bluetooth is not available", Toast.LENGTH_LONG).show();
            activity.finish();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        // If BT is not on, request that it be enabled.
        // setupChat() will then be called during onActivityResult
        if (!adapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
            // Otherwise, setup the chat session
        } else if (connection == null) {
            setupChat();
        }
    }

    private void setupChat() {
        //conversationAdapter = new ArrayAdapter<String>(getActivity(), R.layout.message);

        //listViewConversation.setAdapter(conversationAdapter);

        onButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                sendCommand(1);
            }
        });

        offButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                sendCommand(0);
            }
        });

        // Initialize the BluetoothChatService to perform bluetooth connections
        connection = new BluetoothConnection(handler);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_CONNECT_DEVICE_SECURE:
                // When DeviceListActivity returns with a device to connect
                if (resultCode == Activity.RESULT_OK) {
                    connectDevice(data);
                }
                break;
            case REQUEST_ENABLE_BT:
                // When the request to enable Bluetooth returns
                if (resultCode == Activity.RESULT_OK) {
                    // Bluetooth is now enabled, so set up a chat session
                    setupChat();
                } else {
                    // User did not enable Bluetooth or an error occurred
                    Toast.makeText(getActivity(), "Bluetooth not enable", Toast.LENGTH_SHORT).show();
                    getActivity().finish();
                }
        }
    }

    private void connectDevice(Intent data) {
        // Get the device MAC address
        String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
        // Get the BluetoothDevice object
        BluetoothDevice device = adapter.getRemoteDevice(address);
        // Attempt to connect to the device
        connection.connect(device);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.secure_connect_scan: {
                // Launch the DeviceListActivity to see devices and do scan
                Intent serverIntent = new Intent(getActivity(), DeviceListActivity.class);
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
                return true;
            }
        }
        return false;
    }

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

    private void setStatus(CharSequence subTitle) {
        FragmentActivity activity = getActivity();
        if (null == activity) {
            return;
        }
        final ActionBar actionBar = activity.getActionBar();
        if (null == actionBar) {
            return;
        }
        actionBar.setSubtitle(subTitle);
    }

    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            FragmentActivity activity = getActivity();
            switch (msg.what) {
                case Constants.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BluetoothConnection.STATE_CONNECTED:
                            String name = getString(R.string.title_connected_to, deviceName);
                            setStatus(name);
                            break;
                        case BluetoothConnection.STATE_CONNECTING:
                            setStatus("Connecting...");
                            break;
                        case BluetoothConnection.STATE_NONE:
                            setStatus("Not connected");
                            break;
                        case BluetoothConnection.STATE_LISTEN:
                    }
                    break;
                case Constants.MESSAGE_DEVICE_NAME:
                    deviceName = msg.getData().getString(Constants.DEVICE_NAME);
                    if (activity != null) {
                        Toast.makeText(activity, "Connected to " + deviceName, Toast.LENGTH_SHORT).show();
                    }
                    break;
                case Constants.MESSAGE_TOAST:
                    if (null != activity) {
                        Toast.makeText(activity, msg.getData().getString(Constants.TOAST), Toast.LENGTH_SHORT).show();
                    }
                    break;
                case Constants.MESSAGE_READ:
                    byte[] readBuffer = (byte[]) msg.obj;

                    //Bitmap bmp = BitmapFactory.decodeByteArray(readBuffer, 0, msg.arg1);
                    //im.setImageBitmap(bmp);

                    String path = activity.getFilesDir() + "/mano.xml";

                    writeBytesToOutputStream(readBuffer, path);

                    break;
            }
        }
    };

    private void sendCommand(int command) {
        if (connection.getState() != BluetoothConnection.STATE_CONNECTED) {
            Toast.makeText(getActivity(), "You are not connected!", Toast.LENGTH_LONG).show();
            return;
        }

        byte[] bytes = ByteBuffer.allocate(4).putInt(command).array();
        connection.write(bytes);
    }

    private void writeBytesToOutputStream(byte[] bytes, String path) {

        File file = new File(path);
        OutputStream out;
        try {
            if(file.exists()){
                file.delete();
            }
            file.createNewFile();

            out = new FileOutputStream(file);
            out.write(bytes);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        xml.setFile(file);
    }

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

        private XmlPullParserFactory xmlFactoryObject;
        private XmlPullParser myParser;
        private File file;

        String value;

        public XmlParser() {
            try {
                xmlFactoryObject = XmlPullParserFactory.newInstance();
                myParser = xmlFactoryObject.newPullParser();

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

        public void setFile(File file1) {
            file = file1;
            execute();
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            FileInputStream fis = null;
            try {
                if(file == null){ // failas == null
                    Toast.makeText(getActivity(), "NULL", Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(getActivity(), "NOT NULL " + file.getName(), Toast.LENGTH_LONG).show();
                    fis = new FileInputStream(file);
                    myParser.setInput(fis, null);
                    fis.close();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected String doInBackground(Void... params) {
            int event;
            try {
                event = myParser.getEventType();

                while (event != XmlPullParser.END_DOCUMENT) {
                    String name = myParser.getName();
                    switch (event) {
                        case XmlPullParser.START_TAG:

                            break;

                        case XmlPullParser.END_TAG:

                            if (name.equals("from")) {
                                value = myParser.getAttributeValue(null, "value");
                                System.out.println("JUST FOR TEST " + value);
                                event = XmlPullParser.END_DOCUMENT;
                            }
                            break;

                        default:
                            break;
                    }
                    try {
                        event = myParser.next();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }catch (XmlPullParserException e) {
                e.printStackTrace();
            }
            return value;
        }

        @Override
        protected void onPostExecute(String aVoid) {
            super.onPostExecute(aVoid);
            System.out.println("myEND " + aVoid);
            Toast.makeText(getActivity(), "THE END!!! " + aVoid, Toast.LENGTH_LONG).show();
        }
    }
}

修改

我的文件

<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

3 个答案:

答案 0 :(得分:1)

只是一个猜测,但这可能是你的问题

       try {
            event = myParser.next();
       } catch (IOException e) {
            e.printStackTrace();
       }

这是因为如果由于某种原因你的解析器无法移动到下一个元素 - 也许你的xml没有正确格式化? - 然后这个错误永远不会升级,从而让你陷入无限循环。

你可以做的是打电话&#34;打破&#34;。如果抛出异常。另外,使用Log类进行日志记录,如下所示:

       try {
            event = myParser.next();
       } catch (IOException e) {
            Log.d(TAG, e.getLocalizedMessage();
            break;
       }

答案 1 :(得分:0)

试试这个:

while (myParser.getEventType() != XmlPullParser.END_DOCUMENT) {
        //code       
}

答案 2 :(得分:0)

我想我解决了这个问题。我需要关闭FileInputStream上的onPostExecute而不是onPreExecute方法。