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

Ответить
Аватара пользователя
IlyaZh
Сообщения: 32
Зарегистрирован: 14 июл 2012, 09:52
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение IlyaZh » 21 июл 2012, 19:23

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

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

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

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

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

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

Сообщение Finch » 21 июл 2012, 20:15

Логика не правильная, записывать в файл не нужно

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

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

          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;
	}
в асинктаске вызываем и кормим парсеру
CEO of a company R.id.team

Аватара пользователя
IlyaZh
Сообщения: 32
Зарегистрирован: 14 июл 2012, 09:52
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение IlyaZh » 22 июл 2012, 10:31

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

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

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

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

Сообщение Finch » 22 июл 2012, 12:32

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>
CEO of a company R.id.team

Аватара пользователя
IlyaZh
Сообщения: 32
Зарегистрирован: 14 июл 2012, 09:52
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение IlyaZh » 22 июл 2012, 12:48

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

Верно?


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

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

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

Сообщение Finch » 22 июл 2012, 14:33

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уется(например наполняем адаптер и выводим его в лист, "прячем" прогресс)

}
CEO of a company R.id.team

Аватара пользователя
IlyaZh
Сообщения: 32
Зарегистрирован: 14 июл 2012, 09:52
Откуда: Санкт-Петербург
Контактная информация:

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

Сообщение IlyaZh » 22 июл 2012, 18:14

Большое спасибо! Разобрался!

antleo
Сообщения: 5
Зарегистрирован: 07 авг 2012, 13:58

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

Сообщение antleo » 07 авг 2012, 14:36

Добрый день. Я только начинаю программировать, поэтому не "бейте" сильно, но я так и не понял: метод 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();
}
}
}

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

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

Сообщение Finch » 07 авг 2012, 15:35

asynctask юзай)
Последний раз редактировалось Finch 07 авг 2012, 15:42, всего редактировалось 1 раз.
CEO of a company R.id.team

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

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

Сообщение rezak90 » 07 авг 2012, 15:36

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

antleo
Сообщения: 5
Зарегистрирован: 07 авг 2012, 13:58

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

Сообщение antleo » 07 авг 2012, 16:04

В 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>

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

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

Сообщение rezak90 » 07 авг 2012, 16:41

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

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

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

Сообщение Finch » 07 авг 2012, 16:50

не будет работать без asynctask
CEO of a company R.id.team

antleo
Сообщения: 5
Зарегистрирован: 07 авг 2012, 13:58

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

Сообщение antleo » 07 авг 2012, 17:37

Спасибо, маленько глючно, но работает. 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

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

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

Сообщение Finch » 14 авг 2012, 15:21

clean сделай
CEO of a company R.id.team

Ответить