Проблема вывода Toast из методов других классов

Ответить
bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

Проблема вывода Toast из методов других классов

Сообщение bagrusss » 08 дек 2013, 00:48

Суть такая: у меня есть класс со статическимим методами, предназначенными для испозьзования в разных классах (активностях, сервисах).

В методах создается стандартный java поток. Как только выполнение кодов доходит до Toast - приложение вылетает. как быть в такой ситуации? Мне нужен класс с методами для вызова из других классов, чтобы этот метод делал все: выводил Toast, обновлял интерфейс активности, которая его вызвала!

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

 import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

public class Wall {// мой класс со статическим методом

	private static final String TAG_Send_Error = "Send_error";
	static String res;

	public Wall() {

	}

	public static void Post(final Context context, final String owner_id, final String message,
			final String access_token) {
		res = "ok";

		new Thread(new Runnable() {

			@Override
			public void run() {

				// упаковка параметров
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				params.add(new BasicNameValuePair("owner_id", owner_id));
				params.add(new BasicNameValuePair("message", message
						+ Constants.addtext));
				params.add(new BasicNameValuePair("v", Constants.API_VERSION));
				params.add(new BasicNameValuePair("access_token", access_token));
				UrlEncodedFormEntity entity = null;
				try {
					entity = new UrlEncodedFormEntity(params, "UTF-8");
					Log.d("send", "start message sending");
					HttpPost request = new HttpPost(Constants.API_URI
							+ "wall.post");
					request.setEntity(entity);// добавление параметров в зарпос
					Log.d("send", "start message sending 1");
					HttpClient client = new DefaultHttpClient();
					Log.d("send", "start message sending 2");
					HttpResponse response = null;
					response = client.execute(request);
					Log.d("send", "start message sending 3");
					HttpEntity entry = response.getEntity();
					Log.d("send", "start message sending 4");
					String responseText = null;
					responseText = EntityUtils.toString(entry);
					Log.d("send", responseText.toString());
					JSONObject json = null;
					json = new JSONObject(responseText);
					if (json.has("error")) {
						json = json.getJSONObject("error");
						int err = json.getInt("error_code");
						switch (err) {
						case 0 - 15:
							res = json.getString("error_msg");
							break;
						case 16:

							break;
						case 17:

							break;
						case 100:
							res = "Пропущен один из параметров";
							break;
						}
					} else {
						res = "Успешно!";
					}
				} catch (JSONException e) {
					Log.e(TAG_Send_Error, e.toString());
				} catch (UnsupportedEncodingException e1) {
					Log.e(TAG_Send_Error, e1.toString());
				} catch (ClientProtocolException e) {
					Log.e(TAG_Send_Error, e.toString());
				} catch (IOException e) {
					Log.e(TAG_Send_Error, e.toString());
				} catch (ParseException e) {
					Log.e(TAG_Send_Error, e.toString());
				}
				Toast.makeText(context, res, 3).show();
				// return res;
			}
		});
	}
}

//класс вызывающий метод

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

 
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;

public class SendTestActivity extends Activity implements OnClickListener {

	private EditText id_edit, txtedit;
	private RadioButton sms_btn, wall_btn;
	private Button sendbtn;

	SharedPreferences prf;

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

		prf = PreferenceManager.getDefaultSharedPreferences(this);

		id_edit = (EditText) findViewById(R.id.Send_a_id);
		txtedit = (EditText) findViewById(R.id.Send_A_text);
		sms_btn = (RadioButton) findViewById(R.id.Send_A_sms);
		wall_btn = (RadioButton) findViewById(R.id.Send_A_wall);
		sendbtn = (Button) findViewById(R.id.Send_A_sendbtn);
		sendbtn.setOnClickListener(this);
		prf = PreferenceManager.getDefaultSharedPreferences(this);

	}

	@Override
	public void onClick(View v) {

		switch (v.getId()) {
		case R.id.Send_A_sendbtn:

			if (sms_btn.isChecked()) {

			}
			if (wall_btn.isChecked()) {
						Wall.Post(getApplicationContext(),
id_edit.getText().toString(), txtedit.getText().toString(), prf.getString("access_token", ""));
						
					}
			}
			txtedit.setText("");
			//Toast.makeText(getApplicationContext(), "Успешно отправлено", 3).show();
		}
	}
}

Пробовал убирать создание потока из метода Post, и делать в классе SendTestActivity вот такую вещь:

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

 
			runOnUiThread(new Runnable() {
					
					@Override
					public void run() {
						Wall.Post(id_edit.getText().toString(), txtedit.getText()
								.toString(), 
prf.getString("access_token", ""));
						Toast.makeText(getApplicationContext(), "ok", 3).show();
					}
				});


,но приложение вылетает перед выполнением метода или при начале выполнения метода!
как мне быть? Знаю, что есть ASyncTask, но для каждого метода не хочу создавать класс потомок.
Нужен класс с универсальными функциями для вызова откудаугодно и взаимодействия с интерфейсом.
Последний раз редактировалось bagrusss 08 дек 2013, 01:22, всего редактировалось 1 раз.

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

Re: Проблема вывода Toast из методов других классов

Сообщение rezak90 » 08 дек 2013, 01:04

1) код нужно приводить в соответствующие теги, ибо читать не возможно;
2) если где то что то падает, первым что нужно - смотреть в лог, если в логе не разбираемся то выкладываем его сюда;
bagrusss писал(а):Мне нужен класс с методами для вызова из других классов, чтобы этот метод делал все: выводил Toast, обновлял интерфейс активности, которая его вызвала!
Если такой вопрос стоит, то нужно начинать с ООП, знал бы что такое ссылка и интерфейс то вопрос отпал сам собой. И почитай что такое Observer.
R.id.team
Политика на форуме запрещена

bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

Re: Проблема вывода Toast из методов других классов

Сообщение bagrusss » 08 дек 2013, 01:29

rezak90 писал(а):1) код нужно приводить в соответствующие теги, ибо читать не возможно;
2) если где то что то падает, первым что нужно - смотреть в лог, если в логе не разбираемся то выкладываем его сюда;
bagrusss писал(а):Мне нужен класс с методами для вызова из других классов, чтобы этот метод делал все: выводил Toast, обновлял интерфейс активности, которая его вызвала!
Если такой вопрос стоит, то нужно начинать с ООП, знал бы что такое ссылка и интерфейс то вопрос отпал сам собой. И почитай что такое Observer.
Я пробовал передавать в качестве параметра указатель на класс SendTestActivity в метод Post и создавать поток таким образом:

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

public static void Post(SendTestActivity act, .....){
    act.runOnUiThread(new Runnable() {
                 public void run() {

                     //код моего метода
                     Toast.makeText(act.getApplicationContext(),...);
                }
            });
}
вызов:

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

Wall.Post(this, ...);
но приложение все равно вылетает.

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

Re: Проблема вывода Toast из методов других классов

Сообщение rezak90 » 08 дек 2013, 01:55

так а логи где?
R.id.team
Политика на форуме запрещена

bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

Re: Проблема вывода Toast из методов других классов

Сообщение bagrusss » 08 дек 2013, 02:29

rezak90 писал(а):так а логи где?
Итак вариант 1: когда я убрал создание потока из метода Post

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

				runOnUiThread(new Runnable() {
					
					@Override
					public void run() {
						Wall.Post(id_edit.getText().toString(), txtedit.getText()
								.toString(), prf.getString("access_token", ""));
						Toast.makeText(getApplicationContext(), "ok", 3).show();
					}
				});

  • 12-08 03:16:21.596: D/MY(31570): Отправка записи на стену
    12-08 03:16:21.611: D/send(31570): start message sending
    12-08 03:16:21.611: D/send(31570): start message sending 1
    12-08 03:16:21.616: D/send(31570): start message sending 2
    12-08 03:16:21.646: D/AndroidRuntime(31570): Shutting down VM
    12-08 03:16:21.646: W/dalvikvm(31570): threadid=1: thread exiting with uncaught exception (group=0x41e172a0)
    12-08 03:16:21.711: E/AndroidRuntime(31570): FATAL EXCEPTION: main
    12-08 03:16:21.711: E/AndroidRuntime(31570): android.os.NetworkOnMainThreadException
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at java.net.InetAddress.getAllByName(InetAddress.java:214)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at com.easydevteam.pozdravlenia.Wall.Post(Wall.java:62)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at com.easydevteam.pozdravlenia.SendTestActivity$1.run(SendTestActivity.java:62)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.app.Activity.runOnUiThread(Activity.java:4784)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at com.easydevteam.pozdravlenia.SendTestActivity.onClick(SendTestActivity.java:58)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.view.View.performClick(View.java:4232)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.view.View$PerformClick.run(View.java:17298)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.os.Handler.handleCallback(Handler.java:615)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.os.Handler.dispatchMessage(Handler.java:92)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.os.Looper.loop(Looper.java:137)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at android.app.ActivityThread.main(ActivityThread.java:4921)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at java.lang.reflect.Method.invokeNative(Native Method)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at java.lang.reflect.Method.invoke(Method.java:511)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
    12-08 03:16:21.711: E/AndroidRuntime(31570): at dalvik.system.NativeStart.main(Native Method)

Вариант 2:

Когда вызываю метод Post и поток создается в методе

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

Wall.Post(getApplicationContext(), id_edit.getText().toString(), txtedit.getText().toString(), prf.getString("access_token", ""));
						Toast.makeText(getApplicationContext(), "ok", 3).show();

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

public static void Post(final Context context ,final String owner_id, final String message,
			final String access_token) {
		res = "";

		new Thread(new Runnable() {

			@Override
			public void run() {

                                             //код
  				Toast.makeText(context, res, 3).show();

			}

		}).start();
  • 12-08 03:27:25.391: D/MY(32410): Отправка записи на стену
    12-08 03:27:25.426: D/send(32410): start message sending
    12-08 03:27:25.431: D/send(32410): start message sending 1
    12-08 03:27:25.471: D/send(32410): start message sending 2
    12-08 03:27:25.881: D/send(32410): start message sending 3
    12-08 03:27:25.886: D/send(32410): start message sending 4
    12-08 03:27:25.891: W/dalvikvm(32410): threadid=16: thread exiting with uncaught exception (group=0x41e172a0)
    12-08 03:27:25.901: E/AndroidRuntime(32410): FATAL EXCEPTION: Thread-2496
    12-08 03:27:25.901: E/AndroidRuntime(32410): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    12-08 03:27:25.901: E/AndroidRuntime(32410): at android.os.Handler.<init>(Handler.java:121)
    12-08 03:27:25.901: E/AndroidRuntime(32410): at android.widget.Toast$TN.<init>(Toast.java:361)
    12-08 03:27:25.901: E/AndroidRuntime(32410): at android.widget.Toast.<init>(Toast.java:97)
    12-08 03:27:25.901: E/AndroidRuntime(32410): at android.widget.Toast.makeText(Toast.java:254)
    12-08 03:27:25.901: E/AndroidRuntime(32410): at com.easydevteam.pozdravlenia.Wall$1.run(Wall.java:102)
    12-08 03:27:25.901: E/AndroidRuntime(32410): at java.lang.Thread.run(Thread.java:856)
Вариант 3. Передаю указатель на класс SendTestActivity и создаю поток методом runOnUiThread :

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

Wall.Post(this, id_edit.getText().toString(), txtedit.getText()
								.toString(), prf.getString("access_token", ""));

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

public static void Post(final SendTestActivity act ,final String owner_id, final String message,
			final String access_token) {
		res = "ok";

		act.runOnUiThread (new Runnable() {

			@Override
			public void run() {

                                            // упаковка параметров
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				params.add(new BasicNameValuePair("owner_id", owner_id));
				params.add(new BasicNameValuePair("message", message
						+ Constants.addtext));
				params.add(new BasicNameValuePair("v", Constants.API_VERSION));
				params.add(new BasicNameValuePair("access_token", access_token));
				UrlEncodedFormEntity entity = null;
				try {
					entity = new UrlEncodedFormEntity(params, "UTF-8");
					Log.d("send", "start message sending");
					HttpPost request = new HttpPost(Constants.API_URI
							+ "wall.post");
					request.setEntity(entity);// добавление параметров в зарпос
					Log.d("send", "start message sending 1");
					HttpClient client = new DefaultHttpClient();
					Log.d("send", "start message sending 2");
					HttpResponse response = null;
					response = client.execute(request);
					Log.d("send", "start message sending 3");
					HttpEntity entry = response.getEntity();
					Log.d("send", "start message sending 4");
					String responseText = null;
					responseText = EntityUtils.toString(entry);
					Log.d("send", responseText.toString());
					JSONObject json = null;
					json = new JSONObject(responseText);
					if (json.has("error")) {
						json = json.getJSONObject("error");
						int err = json.getInt("error_code");
						switch (err) {
						case 0 - 15:
							res = json.getString("error_msg");
							break;
						case 16:

							break;
						case 17:

							break;
						case 100:
							res = "Пропущен один из параметров";
							break;
						}
					} else {
						res = "Успешно!";
					}
				} catch (JSONException e) {
					Log.e(TAG_Send_Error, e.toString());
				} catch (UnsupportedEncodingException e1) {
					Log.e(TAG_Send_Error, e1.toString());
				} catch (ClientProtocolException e) {
					Log.e(TAG_Send_Error, e.toString());
				} catch (IOException e) {
					Log.e(TAG_Send_Error, e.toString());
				} catch (ParseException e) {
					Log.e(TAG_Send_Error, e.toString());
				}
                                          	Toast.makeText(act.getApplicationContext(), res, 3).show();
			}

		});
	}
}
  • 12-08 03:38:42.711: D/MY(633): Отправка записи на стену
    12-08 03:38:42.736: D/send(633): start message sending
    12-08 03:38:42.736: D/send(633): start message sending 1
    12-08 03:38:42.736: D/send(633): start message sending 2
    12-08 03:38:42.771: D/AndroidRuntime(633): Shutting down VM
    12-08 03:38:42.771: W/dalvikvm(633): threadid=1: thread exiting with uncaught exception (group=0x41e172a0)
    12-08 03:38:42.826: E/AndroidRuntime(633): FATAL EXCEPTION: main
    12-08 03:38:42.826: E/AndroidRuntime(633): android.os.NetworkOnMainThreadException
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
    12-08 03:38:42.826: E/AndroidRuntime(633): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
    12-08 03:38:42.826: E/AndroidRuntime(633): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
    12-08 03:38:42.826: E/AndroidRuntime(633): at java.net.InetAddress.getAllByName(InetAddress.java:214)
    12-08 03:38:42.826: E/AndroidRuntime(633): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
    12-08 03:38:42.826: E/AndroidRuntime(633): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    12-08 03:38:42.826: E/AndroidRuntime(633): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    12-08 03:38:42.826: E/AndroidRuntime(633): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
    12-08 03:38:42.826: E/AndroidRuntime(633): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
    12-08 03:38:42.826: E/AndroidRuntime(633): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
    12-08 03:38:42.826: E/AndroidRuntime(633): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
    12-08 03:38:42.826: E/AndroidRuntime(633): at com.easydevteam.pozdravlenia.Wall$1.run(Wall.java:62)
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.app.Activity.runOnUiThread(Activity.java:4784)
    12-08 03:38:42.826: E/AndroidRuntime(633): at com.easydevteam.pozdravlenia.Wall.Post(Wall.java:39)
    12-08 03:38:42.826: E/AndroidRuntime(633): at com.easydevteam.pozdravlenia.SendTestActivity.onClick(SendTestActivity.java:59)
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.view.View.performClick(View.java:4232)
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.view.View$PerformClick.run(View.java:17298)
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.os.Handler.handleCallback(Handler.java:615)
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.os.Handler.dispatchMessage(Handler.java:92)
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.os.Looper.loop(Looper.java:137)
    12-08 03:38:42.826: E/AndroidRuntime(633): at android.app.ActivityThread.main(ActivityThread.java:4921)
    12-08 03:38:42.826: E/AndroidRuntime(633): at java.lang.reflect.Method.invokeNative(Native Method)
    12-08 03:38:42.826: E/AndroidRuntime(633): at java.lang.reflect.Method.invoke(Method.java:511)
    12-08 03:38:42.826: E/AndroidRuntime(633): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
    12-08 03:38:42.826: E/AndroidRuntime(633): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
    12-08 03:38:42.826: E/AndroidRuntime(633): at dalvik.system.NativeStart.main(Native Method)

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

Re: Проблема вывода Toast из методов других классов

Сообщение rezak90 » 08 дек 2013, 02:40

1) NetworkOnMainThreadException. Все сетевые операции должны выполняться асинхронно;
2) Can't create handler inside thread that has not called Looper.prepare(). Нелзья обращаться к UI из других потоков (в твоём случае ты вызываешь Toast);
3) смотри 1
R.id.team
Политика на форуме запрещена

bagrusss
Сообщения: 22
Зарегистрирован: 08 дек 2013, 00:17

Re: Проблема вывода Toast из методов других классов

Сообщение bagrusss » 08 дек 2013, 02:52

rezak90 писал(а):1) NetworkOnMainThreadException. Все сетевые операции должны выполняться асинхронно;
Я так понял, что вызывая метод runOnUiThread я не создаю потока....

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

Re: Проблема вывода Toast из методов других классов

Сообщение rezak90 » 08 дек 2013, 12:04

bagrusss писал(а):
rezak90 писал(а):1) NetworkOnMainThreadException. Все сетевые операции должны выполняться асинхронно;
Я так понял, что вызывая метод runOnUiThread я не создаю потока....
нет, но это не причём, так как ты обращаешься к сети с главного потока
R.id.team
Политика на форуме запрещена

Ответить