Страница 2 из 3

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 02 май 2013, 15:48
spheros
rezak90 писал(а):показывайте код, иначе это гадания на кофейной гуще
Вот код:

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

public class MainActivity extends Activity {

	final String LOG_TAG = "myLogs";
	MyTask mt1, mt2, mt3;

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

	public void onclick(View v) {
		switch (v.getId()) {
		case R.id.btnStart1:
			mt1 = new MyTask(1);
			mt2 = new MyTask(2);
			mt3 = new MyTask(3);
			
			mt1.execute();
			mt2.execute();
			mt3.execute();
			break;
		}
	}

	private class MyTask extends AsyncTask<Void, Void, Integer> {

		private int innstanceNum;
		
		public MyTask(int instanceNum) {
			this.innstanceNum = instanceNum;
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			Log.d(LOG_TAG, "Begin instance " + innstanceNum);
		}

		@Override
		protected Integer doInBackground(Void... params) {
			try {
				Log.d(LOG_TAG, "Trying to sleep instance " + innstanceNum);
				TimeUnit.SECONDS.sleep(5);
				Log.d(LOG_TAG, "Instanse " + innstanceNum + " sleeped 5 seconds");
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
			return 100500;
		}

		@Override
		protected void onPostExecute(Integer result) {
			super.onPostExecute(result);
			Log.d(LOG_TAG, "Instanse " + innstanceNum + " end. Result = " + result);
		}
	}
}

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 03 май 2013, 15:52
spheros
Нашел решение в официальном мануале по AsyncTask. Оказалось что для параллельного выполнения задач, начиная с Android 3.0, необходимо запускать их не с помощью execute(), а с помощью executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR). execute() же выполняет задачи последовательно, одну за другой. Блин, оказывается и на этом форуме это уже обсуждалось. Я плохо искал)))

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 03 май 2013, 17:52
rezak90
spheros писал(а):Нашел решение в официальном мануале по AsyncTask. Оказалось что для параллельного выполнения задач, начиная с Android 3.0, необходимо запускать их не с помощью execute(), а с помощью executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR). execute() же выполняет задачи последовательно, одну за другой. Блин, оказывается и на этом форуме это уже обсуждалось. Я плохо искал)))
и ещё добавлю что на 3 > в пуле больше 5-ти потоков не будет крутится

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 15 июл 2013, 22:09
Dmitry88
Всем привет! У меня возникла проблемка. Суть в том, что есть активити, которое делает одну вещь: выводит информацию из БД и связывает ее с ListView. Если мы перешли просто через меню на этот активити, то вызывается одна функция и отображаются все записи из базы, а если через поисковый запрос из другого активити, то тогда выводим только поисковые результаты. Немного подумав, я пришел к выводу, что стоит функции извлечения данных из БД выполнять в другом потоке, ибо записей в базе может быть несколько тысяч. Проблема в том, что не могу передать результат в виде курсора из метода onPostExecute, переменная cursor не обновляется. Как до нее достучаться, уважаемые? Вот мой кусок кода:

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

import ...

public class AllOrdersActivityShort extends Activity{
	
//...
	ListView lv;
	SimpleCursorAdapter scAdapter;
	Cursor cursor;
        final int SHOW_PROGRESS = 0;
	final int CLOSE_PROGRESS = 1;
	AlertDialog dialog;
	MyAsyncTask mt;
        public final int ALLORDERS = 1;
	public final int QUICK_SEARCH = 2;
        //...

    public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.all_orders);

	    // подключаемся к БД
	    db = new DB(this);
	    db.open();
	    mt = new MyAsyncTask();
	    
	    dialog = DialogScreen.getDialog(this, DialogScreen.PROGRESS);
        
        if( getIntent().hasExtra("QUICK_SEARCH_QUERY") ){
        	this.setTitle("Результаты поиска");
        	quick_search_query = getIntent().getStringExtra("QUICK_SEARCH_QUERY");
        	mt.execute(QUICK_SEARCH);
        	Log.d(LOG_TAG, "QUICK SEARCH = " + cursor); //выводит cursor = null
        }else{
        	mt.execute(ALLORDERS);
		Log.d(LOG_TAG, "ALL ORDERS = " + cursor); //выводит cursor = null
        }
 
        startManagingCursor(cursor);
        // далее прицепляем адаптер к ListView 

    }// END onCREATE


    public class MyAsyncTask extends AsyncTask<Integer, Void, Cursor> {
	    	Cursor taskcursor;
	    	
	    	@Override
	        protected void onPreExecute() {
	          super.onPreExecute();
	          dialog.show();
	        }
	    	
	    	@Override
	    	protected Cursor doInBackground(Integer... params) {
	    		switch (params[0]) {
		    		case ALLORDERS:
		    			taskcursor = db.getAllShortOrders();
		    			break;
		    			
		    		case QUICK_SEARCH:
		    			taskcursor = db.quicklySearch(quick_search_query);
		    			break;
					default:
		    			break;
	    		}
	    		return taskcursor;
	    	}
	    	
	    	@Override
	    	protected void onPostExecute(Cursor result) {
	    		super.onPostExecute(cursor);
	    		dialog.dismiss();
	    		Toast.makeText(getApplicationContext(), "Найдено записей: "+result.getCount(), Toast.LENGTH_LONG).show();// работает, выводит число полученных записей
	    		cursor = result;
	        }

	    }


Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 16 июл 2013, 00:02
rezak90
в onPostExecute после cursor = result; нужно сделать startManagingCursor(cursor);
P.S. замечу что сам функционал вида startManagingCursor(cursor); уже deprecated, нужно использовать LoaderManager

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 16 июл 2013, 08:53
Dmitry88
Дописал startManagingCursor(cursor), к сожалению это не решило проблему. Почему-то переменная cursor, объявленная вначале класса AllOrdersActivityShort, никак не хочет менять свое значение :(

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 18 июл 2013, 14:42
Dmitry88
Неужели никто не знает в чем может быть проблема?

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 18 июл 2013, 14:53
Foenix
Dmitry88 писал(а): У меня возникла проблемка. Суть в том, что есть активити, которое делает одну вещь: выводит информацию из БД и связывает ее с ListView. Если мы перешли просто через меню на этот активити, то вызывается одна функция и отображаются все записи из базы, а если через поисковый запрос из другого активити, то тогда выводим только поисковые результаты.
Какая разница - поисковые результаты или все данные- тут нужно можно писать универсальный метод и обрабатывать его одинаково

Я не сильна в асинктасках, но в этом вашем коде

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

if( getIntent().hasExtra("QUICK_SEARCH_QUERY") ){ 
            this.setTitle("Результаты поиска"); 
            quick_search_query = getIntent().getStringExtra("QUICK_SEARCH_QUERY"); 
            mt.execute(QUICK_SEARCH); 
            Log.d(LOG_TAG, "QUICK SEARCH = " + cursor); //выводит cursor = null 
        }else{ 
            mt.execute(ALLORDERS); 
        Log.d(LOG_TAG, "ALL ORDERS = " + cursor); //выводит cursor = null 
        } 
  
        startManagingCursor(cursor); 
Поток пошел сам по себе, а startManagingCursor его не дожидается, выполняется параллельно. Может быть поэтому у вас в нем нет данных.
Попробуйте после получения курсора потоком ПО ЕГО ЗАВЕРШЕНИИ (т.е. в методе onPostExecute)
сделать

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

курсор.requery();
	адаптер.notifyDataSetChanged();
Но помните, что все эти requery тоже deprecated

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 19 июл 2013, 00:50
Dmitry88
Не прокатило:
курсор.requery();
адаптер.notifyDataSetChanged();
Зато наткнулся на такой замечательный метод:

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

scAdapter.changeCursor(result);
после него конечно же выполнил startManagingCursor(result); и вот оно счастье!!! :D
Foenix, спасибо за наводку)

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 20 июл 2013, 12:38
Wadim
Ребят, вот смотрите, я с горем пополам смог написать программку которая отправляет на сервер данные($_post) и получает результат в формате json. делал по примеру одного урока
Так вот, теперь возникла другая задачка над которой бьюсь довольно долго но ниче не могу сообразить.
Нужно чтобы программа постоянно принимала данные, например инфа на сервере изменилась и это тут же отобразилась в программе.
Подскажите как что сделать.
Код MainActivity

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

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import org.apache.http.NameValuePair;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

        public EditText login;
        public EditText pass;
        private ProgressDialog dialog;
        private InputStream is;
        SecondActivity url;

        @Override
        public void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                Button btn = (Button) findViewById(R.id.button1);
                login = (EditText) findViewById(R.id.editText1);
                pass = (EditText) findViewById(R.id.editText2);
                btn.setOnClickListener(new OnClickListener() {

                        @Override
                        public void onClick(View v) {
                                // указываем куда будем конектится
                                new RequestTask().execute("http://myhomepage.hol.es/login.php");
                        }
                });
        }

        class RequestTask extends AsyncTask<String, String, String> {

                @Override
                protected String doInBackground(String... params) {

                        try {
                                //создаем запрос на сервер
                                DefaultHttpClient hc = new DefaultHttpClient();
                                ResponseHandler<String> res = new BasicResponseHandler();
                                //он у нас будет посылать post запрос
                                HttpPost postMethod = new HttpPost(params[0]);
                                //будем передавать два параметра
                                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                                //передаем параметры из наших текстбоксов
                                //лоигн
                                nameValuePairs.add(new BasicNameValuePair("login", login.getText().toString()));
                                //пароль
                                nameValuePairs.add(new BasicNameValuePair("pass", pass.getText().toString()));
                                //собераем их вместе и посылаем на сервер
                                postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                                //получаем ответ от сервера
                                String response = hc.execute(postMethod, res);
                                //посылаем на вторую активность полученные параметры
                                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                                //то что куда мы будем передавать и что, putExtra(куда, что);
                                intent.putExtra(SecondActivity.JsonURL, response.toString());
                                startActivity(intent);
                        } catch (Exception e) {
                                System.out.println("Exp=" + e);
                        }
                        return null;
                }

                @Override
                protected void onPostExecute(String result) {

                        dialog.dismiss();
                        super.onPostExecute(result);
                }

                @Override
                protected void onPreExecute() {

                        dialog = new ProgressDialog(MainActivity.this);
                        dialog.setMessage("Загружаюсь...");
                        dialog.setIndeterminate(true);
                        dialog.setCancelable(true);
                        dialog.show();
                        super.onPreExecute();
                }
        }
}
код SecondActivity

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

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;

public class SecondActivity extends Activity {

        public static String JsonURL;
        private static ArrayList<HashMap<String, Object>> myBooks;
        private static final String FIRST = "firstname";
        private static final String LAST = "lastname";
        public ListView listView;

        /** @param result */
        public void JSONURL(String result) {

                try {
                        //создали читателя json объектов и отдали ему строку - result
                        JSONObject json = new JSONObject(result);
                        //дальше находим вход в наш json им является ключевое слово data
                        JSONArray urls = json.getJSONArray("data");
                        //проходим циклом по всем нашим параметрам
                        for (int i = 0; i < urls.length(); i++) {
                                HashMap<String, Object> hm;
                                hm = new HashMap<String, Object>();
                                //читаем что в себе хранит параметр firstname
                                hm.put(FIRST, urls.getJSONObject(i).getString("firstName").toString());
                                //читаем что в себе хранит параметр lastname
                                hm.put(LAST, urls.getJSONObject(i).getString("lastName").toString());
                                myBooks.add(hm);
                                //дальше добавляем полученные параметры в наш адаптер
                                SimpleAdapter adapter = new SimpleAdapter(SecondActivity.this, myBooks, R.layout.list,
                                                new String[] { FIRST, LAST, }, new int[] { R.id.text1, R.id.text2 });
                                //выводим в листвбю
                                listView.setAdapter(adapter);
                                listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
                        }
                } catch (JSONException e) {
                        Log.e("log_tag", "Error parsing data " + e.toString());
                }
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);
                setContentView(R.layout.url);
                listView = (ListView) findViewById(R.id.list);
                myBooks = new ArrayList<HashMap<String, Object>>();
                //принимаем параметр который мы послылали в manActivity
                Bundle extras = getIntent().getExtras();
                //превращаем в тип стринг для парсинга
                String json = extras.getString(JsonURL);
                //передаем в метод парсинга
                JSONURL(json);
        }
}

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 28 июл 2013, 00:09
Dmitry88
Вот который раз убеждаюсь, что не все так просто в нашем мире)) Моя проблема оказалась все еще живучей, дело в том, что на моем htc sensation описанное мною выше решение работает, однако на htc desire приложение вылетает с ошибкой, к сожалению не знаю с какой. Подозреваю, что это из-за того, что у desire процессор одноядерный и не допускает параллельного выполнения задач, поправьте если не прав. Собственно вопрос в том, можно ли как-то сделать так чтоб и на одноядерных устройствах все работало? Как быть в данной ситуации?

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 28 июл 2013, 01:14
rezak90
Dmitry88 писал(а):Подозреваю, что это из-за того, что у desire процессор одноядерный и не допускает параллельного выполнения задач, поправьте если не прав.
конечно не прав, процесс и поток две разных вещи
Dmitry88 писал(а):дело в том, что на моем htc sensation описанное мною выше решение работает, однако на htc desire приложение вылетает с ошибкой
уже догадываюсь в чём проблема, какие версии андроида на этих телефонах?
Dmitry88 писал(а):приложение вылетает с ошибкой, к сожалению не знаю с какой.
LogCat, не не сылашл :?

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 28 июл 2013, 08:48
Dmitry88
уже догадываюсь в чём проблема, какие версии андроида на этих телефонах?
на sensation 4.2.2, а у desire 4.1.2
LogCat, не не сылашл :?
конечно слышал, но приложение устанавливал мой знакомый к себе на телефон, он просто известил меня об ошибке.

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 30 июл 2013, 23:17
Dmitry88
уже догадываюсь в чём проблема, какие версии андроида на этих телефонах?
не томи, скажи пожалуйста, в чем же проблема?))

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 30 июл 2013, 23:54
rezak90
Dmitry88 писал(а):
уже догадываюсь в чём проблема, какие версии андроида на этих телефонах?
не томи, скажи пожалуйста, в чем же проблема?))
забыл про эту тему... та думал что версии андроидов разные, оказалась и там 4 и там 4... так что здесь увы никак не скажешь в чём причина пока не взглянешь на логи...

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 09 сен 2014, 15:30
LazeR
Подскажите поч весит :(

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

package ua.example.eventsorganizer;
 

import java.util.concurrent.ExecutionException;

import org.json.JSONException;
import org.json.JSONObject;
import BusinessLogic.JSONTransmitter;
import android.os.Bundle;
import android.widget.Toast;
import android.app.Activity;
 
public class test extends Activity {
 
	JSONTransmitter mt;
	
    

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        try {
            JSONObject toSend = new JSONObject();            
            toSend.put("id", "2151");

            JSONTransmitter transmitter = new JSONTransmitter();
            transmitter.execute(new JSONObject[] {toSend});
            JSONObject result = null;
            String result2 = "";
            mt = new JSONTransmitter();
            result = mt.get();
            toSend.put("id", "2151");
            result2 = result.getString("EventId");
            Toast.makeText(this, "get returns " + result2, Toast.LENGTH_LONG).show();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        

    }
}

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

package BusinessLogic;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.util.Log;

public class JSONTransmitter extends AsyncTask<JSONObject, JSONObject, JSONObject> {
	 
    String url = "http://someurl";
 
    @Override
    public JSONObject doInBackground(JSONObject... data) {
        JSONObject json = data[0];
        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 100000);
 
        JSONObject jsonResponse = null;
        HttpPost post = new HttpPost(url);
        try {
            StringEntity se = new StringEntity(json.toString());
            post.addHeader("content-type", "application/json");
            post.setEntity(se);
             
            HttpResponse response;
            response = client.execute(post);
            String resFromServer = org.apache.http.util.EntityUtils.toString(response.getEntity());
 
            jsonResponse=new JSONObject(resFromServer);
            Log.i("Response from server", jsonResponse.getString("EventId"));
           
        } catch (Exception e) { e.printStackTrace();}
         
        return jsonResponse;
    }
 
}

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 09 сен 2014, 15:51
Mikhail_dev
Можно поподробнее? Что значит висит?
Измените таймаут на
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10);
не будет висеть.

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 09 сен 2014, 16:07
LazeR
у меня не таймаут там, просто код роботает, но если я хочу вывести результат методом get, программа перестаёт реагировать

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 09 сен 2014, 16:11
LazeR

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

package my.home.page;
 
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.json.JSONException;
import org.json.JSONObject;
 
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;
 
public class MainActivity extends Activity {
 
	
    private AsyncTask<JSONObject, JSONObject, JSONObject> result;


	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        try {
            JSONObject toSend = new JSONObject();
            toSend.put("id", "2151");
             
            JSONTransmitter transmitter = new JSONTransmitter();
            result=transmitter.execute(new JSONObject[] {toSend});
            
            toSend.put("id", "2151");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        

    }
 

    public class JSONTransmitter extends AsyncTask<JSONObject, JSONObject, JSONObject> {
    	 
        String url = "Some url";
     
        @Override
        public JSONObject doInBackground(JSONObject... data) {
            JSONObject json = data[0];
            HttpClient client = new DefaultHttpClient();
            HttpConnectionParams.setConnectionTimeout(client.getParams(), 100000);
     
            JSONObject jsonResponse = null;
            HttpPost post = new HttpPost(url);
            try {
                StringEntity se = new StringEntity(json.toString());
                post.addHeader("content-type", "application/json");
                post.setEntity(se);
                 
                HttpResponse response;
                response = client.execute(post);
                String resFromServer = org.apache.http.util.EntityUtils.toString(response.getEntity());
     
                jsonResponse=new JSONObject(resFromServer);
                Log.i("Response from server", jsonResponse.getString("EventId"));
               
            } catch (Exception e) { e.printStackTrace();}
             
            return jsonResponse;
        }
     
    }
 
}
Просто нужно что бы jsonResponse возвращало в class MainActivity

Re: Урок 88. AsyncTask. Итоговый результат. Метод get

Добавлено: 09 сен 2014, 16:27
Mikhail_dev
В уроке написано
Мы вызываем метод get, чтобы получить результат работы AsyncTask. Но что будет, если задача еще не завершена, а мы вызвали get? Метод get будет ждать. Т.е. просто блокирует поток, в котором он выполняется, и не отпустит, пока не получит какой-то результат или не выскочит exception.
Я бы не советовал использовать данный метод вообще.
Просто нужно что бы jsonResponse возвращало в class MainActivity
1. Почитайте про лодеры, а если точнее про AsynckTaskLoader. Гугл их представил в Android 3.0 и они будут удобны тут для вашей задачи.
2. Ну или можно сделать вашу задачу через слушатели.
3. ну или можно сделать класс JSONTransmitter внутренним, после чего переопределить еще метод onPostExecute в JSONTransmitter классе и там уже делать то, что вам необходимо.