-1

Это не дубликат вопроса, поставленного выше. Поскольку HAndlerThread запускает newThread, и я получаю исключение NetworkOnMainThread, я думаю, что это странная ошибка. Это совершенно новая проблема для решения этого обычного исключения NetworkOnMainThread. Пожалуйста, отмените это.Handler Thread - исключение NetworkOnMainThread (android.os.handler)

Привет, прежде всего, я занимаюсь HandlerThread. Я использовал Fragment, чтобы запустить handlerthread и отправить сообщение в поток. Внутри сообщения HandlerThread Handle я использую сетевой вызов для загрузки изображений. Затем я отправляю загруженные изображения в поток пользовательского интерфейса с помощью обработчика MainThread. Но при запуске этого приложения я получаю NetworkOnMainThread Exception.Below - это коды для Fragment и Thread Handler.

Фрагмент:

public class LoaderFragment extends Fragment { 
Button loaderButton; 
LoaderThread loadThread; 
Handler loaderThreadHandler; 
Handler mainHandler; 
String[] queArray; 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mainHandler = new Handler(Looper.getMainLooper()); 
    loadThread = new LoaderThread("LoaderThread",mainHandler); 
    queArray = new String[]{"http://www.paynekillers.com/downloads/screens/17_screen05.jpg", 
      "http://www.hdwallpapers.in/walls/jacob_frye_assassins_creed_syndicate-wide.jpg", 
    "http://www.percivalconstantine.com/wp-content/uploads/2015/03/Tomb-Raider-Lara-Croft-Summit-2013.jpg", 
    "http://orig00.deviantart.net/f904/f/2014/155/e/a/batman_arkham_knight_hd_wallpaper_1_by_rajivcr7-d7l19pt.jpg", 
    "http://static5.gamespot.com/uploads/original/536/5360430/2753139-15774024117_9026e0a43c_o.jpg"}; 
} 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View loaderView = inflater.inflate(R.layout.loader_layout, container, false); 
    this.loaderButton = (Button) loaderView.findViewById(R.id.proc_button); 
    return loaderView; 
} 

@Override 
public void onResume() { 
    super.onResume(); 



    loaderButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      loadThread.start(); 
      loaderThreadHandler = loadThread.requestHandler(); 
      Message msg = Message.obtain(loaderThreadHandler, 1, queArray); 
      msg.sendToTarget(); 
     } 
    }); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    loadThread.quit(); 
} } 

Handler Автор:

public class LoaderThread extends HandlerThread implements Handler.Callback{ 
Handler imageHandler; 
Handler loaderHandler; 
Map<Integer,String> queMap; 
HandlerActivity activity; 


public LoaderThread(String name, Handler handler) { 
    super(name); 
    imageHandler= handler; 
    Log.d("inside : ", name); 
} 

Handler requestHandler(){ 
    loaderHandler = new Handler(this.getLooper(),this); 
    return loaderHandler; 
} 


@Override 
public boolean handleMessage(Message msg) { 
    String[] que = (String[]) msg.obj; 
    queMap = new HashMap<Integer,String>(); 
    if(que != null){Log.d("",que[3]);} 
    for (int i=0;i<=4; i++){ 
     String url = que[i]; 

     queMap.put(i,url); 
     Log.d("1",url); 
    } 
    Log.d("THR : ", String.valueOf(Thread.currentThread())); 
    Random rand = new Random(); 
    String link = queMap.get(rand.nextInt(5)); 

    loadImages(link); 
    return true; 
} 

void loadImages(final String url){ 
    Log.d("inside Load :","Inside Load"); 
    try { 
     HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); 
     final Bitmap image = BitmapFactory.decodeStream(connection.getInputStream()); 
     imageHandler.post(new Runnable() { 
      @Override 
      public void run() { 
       activity.loadImage(image, url); 
      } 
     }); 

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

метод LoadImage Activity в:

public void loadImage(Bitmap image, String url) { 
    Bitmap img = image; 
    String link = url; 
    ft = fmg.beginTransaction(); 
    ft.add(R.id.frag_container,imgFrag,"ImageFragment"); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.show(imgFrag); 
    ft.commit(); 
    imgFrag.loadImg(img,link); 

} 

Также Когда я использую журнал, чтобы проверить, какой поток я нахожусь в (внутри handleMessage в HandlerThread) Я получаю сообщение журнала, поскольку я нахожусь в Main. Как это возможно? Я делаю что-то неправильно?

+0

см. [Здесь] (http://stackoverflow.com/a/25096981/2252830) о том, как использовать «HandlerThread» – pskink

+0

«Но я пытаюсь создать совершенно новый HandlerThread» и что я делаю? ? почему вы вообще расширяете «HandlerThread»? в чем причина этого? – pskink

+0

В комментариях очень сложно следить за обсуждением. Пожалуйста, напишите ответ, если он у вас есть, или попросите разъяснить информацию здесь. Если вам нужно провести расширенное обсуждение, используйте один из наших чатов, чтобы облегчить это. –

ответ

-3

Для любых сетевых операций в Android рекомендуется написать этот код внутри AsyncTask.

+1

Это Android101! – zIronManBox

+0

@zIronManBox Я сделал так много примеров Networking и AsyncTask лучше ... !! –

+0

@AjajPatel Задача Async с исполнителем лучше обычной задачи Async –

0

Изменение LoaderFragment из

mainHandler = new Handler(Looper.getMainLooper()); 
loadThread = new LoaderThread("LoaderThread",mainHandler); 

в

loadThread = new LoaderThread("LoaderThread"); 

, а затем в LoaderThread

public LoaderThread(String name, Handler handler) { 
    super(name);   
    Log.d("inside : ", name); 
} 
@Override 
protected void onLooperPrepared() { 
    imageHandler = new Handler(getLooper(), this); 
    } 

Вы получаете ошибку, так как вы передаете лупер UI Thread к LoaderThread , который вы снова передаете в requestHandler() для n сетевой доступ. Следовательно, ваша сетевая операция отменяется с помощью UI Thread Looper.

+0

Спасибо за ваш ответ. Я думаю, что это решает проблему. Но я пытаюсь передать сообщение между двумя потоками. Теперь подумайте об этом, у меня есть Thread1 и Thread 2. Я создал обработчик и подготовил его в каждом потоке. Я могу передать ссылку обработчика thread1 на thread2 и то же самое для thread2. Теперь, что произойдет, если я отправлю сообщение в thread2 из thread1? Будет ли сообщение обработано из первого потока? –

+0

Если вы говорите, что я передаю петлитель UI во второй поток и снова получаю его в запросе-петлере. то же самое происходит, если я отправляю обработчик thread1 в thread2. И если я попробую Thread2 looper, я получу петлитель 1-го потока? –

+0

Я вижу только один поток в вашем примере «LoaderThread loadThread», но чтобы ответить на ваш вопрос, у вас есть цель и источник вашего «сообщения», для которого необходимо предоставить соответствующие обработчики (подумайте о них как _id_s) и когда dequeu сообщение, которое вы затем можете отправить сообщение на другом потоковом элементе, изменив источник и цель. Чтобы настроить их, вы можете передать ссылку на обработчик thread1 при создании thread2 и передать сообщение из thread2. когда поток 1 читает сообщение, он может хранить обработчик источника –

0

У меня была та же проблема. А потом я поставил мой HandlerThread's обработчик в переопределен метод, называемый onLooperPrepared(), и не получил, что исключение больше, так что вы должны попытаться сделать что-то подобное в вашем LoaderThread классе:

@Override 
protected void onLooperPrepared() { 
    super.onLooperPrepared(); 
    loaderHandler = new Handler(this.getLooper(),this); 
} 

onLooperPrepared, согласно documentation , Я цитирую: метод обратного вызова, который может быть явно переопределен при необходимости для выполнения некоторой настройки перед петлями Looper. Пожалуйста, расскажите, если это сработало для вас, или нет.

+0

вам это не нужно: вы можете вызвать 'getLooper()' сразу после того, как вы запустили() 'ed your' HandlerThread' – pskink

+0

, откуда я должен называть' getLooper() '? –

+0

, где бы вы ни хотели, но после вызова 'start()', см. [Здесь] (http://stackoverflow.com/a/25096981/2252830) – pskink

Смежные вопросы