Страница 1 из 1

Как реализовать?

Добавлено: 21 июл 2012, 19:23
IlyaZh
Задача: нужно скачать с сервера xml файл, разобрать его и что-то сделать с данными.

Сейчас для всего этого использую AsyncTask т.к. в нём выполняю скачивание файла, который затем внутри этой функции передаётся в функцию, занимающуюся разбором данных и совершением с ними действия. Однако, при повороте экрана возникают трудности - по окончании действия AsyncTask приложение вылетает с ошибкой, ведь оно пытается закрыть диалоговое окно, которое уже не существует. А использовать связь асинхронной задачи с активности, как в уроке №91 я не могу, т.к. функции скачивания и разбора не могут быть статичными.

Как можно поступить в данной ситуации?

Может скачивать файл и сохранять его во внутренней памяти, но как потом заставить активность прочитать файл только тогда, когда завершиться асинхронная задача? Подскажите пожалуйста.

Re: Как реализовать?

Добавлено: 21 июл 2012, 20:15
Finch
Логика не правильная, записывать в файл не нужно

создаём метод

Код: Выделить всё

          public String getXml(String url) throws SAXException {
               String xml = "";
               InputStream mInputStream = null;
		try {
			DefaultHttpClient mHttpClient = new DefaultHttpClient();
			HttpPost mHttpPost = new HttpPost(url);

			HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
			HttpEntity mHttpEntity = mHttpResponse.getEntity();
			mInputStream = mHttpEntity.getContent();
			BufferedReader mReader = new BufferedReader(new InputStreamReader(
					mInputStream, "UTF-8"), 8); //что6ы не 6ыло крякозя6ров
			StringBuilder mStringBuilder = new StringBuilder();
			String line = null;
			while ((line = mReader.readLine()) != null) {
				mStringBuilder.append(line + "\n");
			}
			mInputStream.close();
			xml = mStringBuilder.toString();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return xml;
	}
в асинктаске вызываем и кормим парсеру

Re: Как реализовать?

Добавлено: 22 июл 2012, 10:31
IlyaZh
Finch писал(а): в асинктаске вызываем и кормим парсеру
Этот метод будет возвращать xml строку? Или как его кормить? Разъясните чуть чуть пожалуйста. Я не могу кормить в асинктакске т.к. если пользователь повернёт экран в это время, то приложение вылетет - ибо внутри цикла парсинга - я сразу же использую эти данные.

Я разбираю xml с помощью xmlPullParser

Re: Как реализовать?

Добавлено: 22 июл 2012, 12:32
Finch
IlyaZh, метод возвращает ваш xml как String, тоесть "полностью ваш xml файл"(строки из него) в одной переменной, и не нужно его никуда сохранять как файл
парсеру кормим переменную
например

Код: Выделить всё

static final String URL = "http://сайт.ком/test.xml";
String test = getXml(URL);
Парсер.распарсить(test);
вот как-то так
п.с.

Код: Выделить всё

<activity
            android:name="Имя твоей активности"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name" >
</activity>

Re: Как реализовать?

Добавлено: 22 июл 2012, 12:48
IlyaZh
Я делаю так.
Создаю переменную String xml;
Затем описываю класс getXml();
Затем внутри асинктаск я делаю xml=getXml("http://site.ru/file.xml");
И затем, в onCreate() после вызова асинктаск делаю parser(xml);

Верно?


Столкнулся с проблемой. Изначально Xml = null;
После выполнения асинктаска она получает какое-то значение.
Как мне запустить парсер в onCreate тогда, когда xml будет не пуста?

Re: Как реализовать?

Добавлено: 22 июл 2012, 14:33
Finch
getXml(String url) - это метод, его можно имплементировать в вашей активности или в отдельном классе
напрмер

Код: Выделить всё

public class GetData {
    public String getXml(String url){
     //....
    //.....
    }
}
импортируем класс, создаём о6ьект класса в вашей активности

Код: Выделить всё

package имя_пакета;
 
import имя_пакета.GetData;

public class MyActivity extends Activity {

static final String URL = "http://сайт.ком/test.xml";

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    GetData mGetData = new GetData();
    new aSyncLoad.execute(URL);
}

class aSyncLoad extends AsyncTask<String, Void, Document>{
//doInBackground отдаём Document 
//например 
@Override
protected Document doInBackground(String... params) {
    publishProgress(new Void[] {});
    String url = "";
    if (params.length > 0) { //на всякий пожарный =)
    url = params[0];
    }
    try{
        String test = mGetData.getXml(url);
        птом  DocumentBuilderFactory, DocumentBuilder юзаем (можно и метод написать отдельно и тут его использовать)
    } catch (NullPointerException  e) { //если инет 6удет отключен то получим ексепшн
        e.getMessage();
        }
    return Документ;
    }
}
//onProgressUpdate показываем прогресс
//onPostExecute делаем все что тре6уется(например наполняем адаптер и выводим его в лист, "прячем" прогресс)

}

Re: Как реализовать?

Добавлено: 22 июл 2012, 18:14
IlyaZh
Большое спасибо! Разобрался!

Re: Как реализовать?

Добавлено: 07 авг 2012, 14:36
antleo
Добрый день. Я только начинаю программировать, поэтому не "бейте" сильно, но я так и не понял: метод getXml() в классе GetData, возвращает xml в виде строки? Если так, то такой код должен вывести в TextView мой xml файл в виде текста? Но он выводит пустую страницу.

package ru.startandroid.develop.test6;
import org.xml.sax.SAXException;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
static final String URL = "http://сайт.ком/test.xml";
GetData mGetData = new GetData();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView1=(TextView) findViewById(R.id.textView1);
try {
String XmlToString=mGetData.getXml(URL);
textView1.setText(XmlToString);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Re: Как реализовать?

Добавлено: 07 авг 2012, 15:35
Finch
asynctask юзай)

Re: Как реализовать?

Добавлено: 07 авг 2012, 15:36
rezak90
antleo писал(а):метод getXml() в классе GetData, возвращает xml в виде строки?
Да ты правильно понял.
А на счёт почему не возвращает то смотри в дебаге в чём проблема. А лучше кинь сюда класс GetData. Ну и посмотреть на манифест было бы не плохо.

Re: Как реализовать?

Добавлено: 07 авг 2012, 16:04
antleo
В GetData лежит метод который Finch опубликовал:

package ru.startandroid.develop.test6;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.SAXException;
public class GetData {
public String getXml(String url) throws SAXException {
String xml = "";
InputStream mInputStream = null;
try {
DefaultHttpClient mHttpClient = new DefaultHttpClient();
HttpPost mHttpPost = new HttpPost(url);
HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
HttpEntity mHttpEntity = mHttpResponse.getEntity();
mInputStream = mHttpEntity.getContent();
BufferedReader mReader = new BufferedReader(new InputStreamReader(
mInputStream, "UTF-8"), 8);
StringBuilder mStringBuilder = new StringBuilder();
String line = null;
while ((line = mReader.readLine()) != null) {
mStringBuilder.append(line + "\n");
}
mInputStream.close();
xml = mStringBuilder.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return xml;
}
}

Манифест не трогал:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.startandroid.develop.test6"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

Re: Как реализовать?

Добавлено: 07 авг 2012, 16:41
rezak90
код даже не стал смотреть, после прочтения сообщения "Манифест не трогал" :D . Добавь следущую строку в манифесте перед apllication:
<uses-permission android:name="android.permission.INTERNET" />
и будет тебе счастье.

Re: Как реализовать?

Добавлено: 07 авг 2012, 16:50
Finch
не будет работать без asynctask

Re: Как реализовать?

Добавлено: 07 авг 2012, 17:37
antleo
Спасибо, маленько глючно, но работает. Asynctask, думаю, глюки уберет)))

Работало, но не долго. После переустановки эмулятора перестал работать код((. Уже все переустановил, но все равно не помогает, может где то ошибку допустил. Помогите, кто знает. Спс.
Как я понимаю, компилятор ломается на этой строке:
DefaultHttpClient mHttpClient = new DefaultHttpClient();

public class GetData {
public String getXml(String url) throws SAXException {
String xml = "";
InputStream mInputStream = null;
try {
DefaultHttpClient mHttpClient = new DefaultHttpClient();
Log.d("My_logs", "point1");
HttpPost mHttpPost = new HttpPost(url);


HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);


HttpEntity mHttpEntity = mHttpResponse.getEntity();
mInputStream = mHttpEntity.getContent();

BufferedReader mReader = new BufferedReader(new InputStreamReader(
mInputStream, "UTF-8"), 8);
StringBuilder mStringBuilder = new StringBuilder();
String line = null;
while ((line = mReader.readLine()) != null) {
mStringBuilder.append(line + "\n");
}
mInputStream.close();


xml = mStringBuilder.toString();
Log.d("My_logs", xml);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return xml;
}
}

Лог ошибок:

08-13 16:04:27.832: E/AndroidRuntime(718): FATAL EXCEPTION: main
08-13 16:04:27.832: E/AndroidRuntime(718): java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.startandroid.develop.p0761tab/ru.startandroid.develop.p0761tab.MainActivity}: java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.startandroid.develop.p0761tab/ru.startandroid.develop.p0761tab.OneActivity}: java.lang.NullPointerException
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.os.Handler.dispatchMessage(Handler.java:99)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.os.Looper.loop(Looper.java:123)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.main(ActivityThread.java:3683)
08-13 16:04:27.832: E/AndroidRuntime(718): at java.lang.reflect.Method.invokeNative(Native Method)
08-13 16:04:27.832: E/AndroidRuntime(718): at java.lang.reflect.Method.invoke(Method.java:507)
08-13 16:04:27.832: E/AndroidRuntime(718): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-13 16:04:27.832: E/AndroidRuntime(718): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-13 16:04:27.832: E/AndroidRuntime(718): at dalvik.system.NativeStart.main(Native Method)
08-13 16:04:27.832: E/AndroidRuntime(718): Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.startandroid.develop.p0761tab/ru.startandroid.develop.p0761tab.OneActivity}: java.lang.NullPointerException
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.startActivityNow(ActivityThread.java:1487)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:654)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.widget.TabHost.setCurrentTab(TabHost.java:326)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.widget.TabHost.addTab(TabHost.java:216)
08-13 16:04:27.832: E/AndroidRuntime(718): at ru.startandroid.develop.p0761tab.MainActivity.onCreate(MainActivity.java:51)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-13 16:04:27.832: E/AndroidRuntime(718): ... 11 more
08-13 16:04:27.832: E/AndroidRuntime(718): Caused by: java.lang.NullPointerException
08-13 16:04:27.832: E/AndroidRuntime(718): at java.io.StringReader.<init>(StringReader.java:46)
08-13 16:04:27.832: E/AndroidRuntime(718): at ru.startandroid.develop.p0761tab.OneActivity.prepareXpp(OneActivity.java:241)
08-13 16:04:27.832: E/AndroidRuntime(718): at ru.startandroid.develop.p0761tab.OneActivity.onCreate(OneActivity.java:99)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-13 16:04:27.832: E/AndroidRuntime(718): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-13 16:04:27.832: E/AndroidRuntime(718): ... 20 more

Re: Как реализовать?

Добавлено: 14 авг 2012, 15:21
Finch
clean сделай