1

主线程当您在Android的网络连接,你是阻塞主线程,所以你必须移动这个任务的“一些”到一个新的线程其操作正好堵在android系统

我有2个在此部分

1-其以下的动作的阻止主线程(A或B)

//A: 
HttpURLConnection c = (HttpURLConnection) (new URL(url)).openConnection(); 

//B: 
InputStream stream=c.getInputStream(); 

2-“两者”上述(A & B)的问题,如果必须在运行新的线程,它有一个坏的影响,运行在一个新的独立的每一个读?看看下面的代码:

//I temporary removed try & catch to simplify the code 
public class connect{ 
HttpURLConnection c; String url; 
public connect(String url){ 
    this.url=url; 
    new Thread(new Runnable{ 
    @override public void run(){ 
    c = (HttpURLConnection) (new URL(url)).openConnection(); 
    } 
}); 

} 
public InputStream get(){ 
    return c.getInputStream(); 
//or make this one in a new thread 

    } 

public InputStream post(Sring params){ 
c.setRequestMethod("POST"); 
//.. make some code for posting data , and then call get() 
//thats why i cannot perform c.getInputStram() at the same time with openConnection() 
return get() 


} 
} 

回答

0

此解决方案使用处理程序来主线程与后台线程(即不HTTP连接东西的线程)

public class MainActivity extends AppCompatActivity { 

Thread mThread; 

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

    startThread(); 
    } 


    public void startThread(){ 
     String url = "www.google.com"; 
     String result = ""; 
    mThread = new Thread(new Runnable() { 
     public void run() { 
      InputStream is = null; 
      HttpURLConnection conn; 
      try { 
       ConnectivityManager connMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 
       NetworkInfo networkInfo = null; 
       if (connMgr != null) { 
        networkInfo = connMgr.getActiveNetworkInfo(); 
       } 
       if (networkInfo != null && networkInfo.isConnected() && !mThread.isInterrupted()) { 
        conn = (HttpURLConnection) url.openConnection(); 
        is = conn.getInputStream(); 

        //Here you get the result from inputStream 


       } 
       threadMsg(result); 

      }catch (IOException e){ 
       e.printStackTrace(); 
      } 
      finally { 
       if (is != null) { 
        try { 
         is.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
     private void threadMsg(String msg) { 

      if (msg != null && !msg.equals("") && !mThread.isInterrupted()) { 
       Message msgObj = handler.obtainMessage(); 
       Bundle b = new Bundle(); 
       b.putString("message", msg); 
       msgObj.setData(b); 
       handler.sendMessage(msgObj); 
      } 
     } 
     private Handler handler = new Handler(Looper.getMainLooper()) { 
      @Override 
      public void handleMessage(Message msg) { 
       String result = msg.getData().getString("message"); 
       // What you want to do in UI thread 
      } 
     }; 

    }); 
    mThread.start(); 
    } 
+0

我想避免的AsyncTask –

+0

好吧,明天我会送一个示例代码与处理程序和尺蠖工作。 –

+0

好的,我在等,先谢谢你 –

1

连接的以下操作的阻塞主线程(A或B)?

很明显,操作A和B都会阻塞主线程。只需调用主线程下面将抛出一个异常(NetworkOnMainThreadException)马上:

HttpURLConnection c = (HttpURLConnection) (new URL(url)).openConnection(); 

此外,当你调用在主线程上以下行:

InputStream stream=c.getInputStream(); 

你只是想通过网络读取字节流。现在有多种因素可以确定完成此操作所需的时间。例如,网络速度,要读取的总字节数等等。应用程序应该不需要等待并保持空闲状态,直到读取过程完成。所有与UI相关的进程应该能够运行并消耗资源,因为用户会对您的应用程序做出反应,这是不可能的,因为正在进行的字节读取过程实际上阻止了主线程。

如果A和B都必须在新线程中运行,那么它的运行效率是否会在一个新的单独线程中运行每个线程?

从技术上来说,是的,在单独的线程中运行都是不好的。除了你为什么要这么做呢?在启动流读取过程之前,您需要确保连接已打开。在单独的线程中调用A和B会引发并发问题。您必须在A之后调用B,所以如果您甚至解决了并发问题,那么创建两个单独的线程将是没有用的。

编辑:

所以,当你在要避免使用AsyncTask评论说。替代方案是Java线程。退房线程下面的示例用法:

static public class MyThread extends Thread { 
    @Override 
    public void run() { 
     try { 

       // add your url and open connecttion here 
       HttpURLConnection c = (HttpURLConnection) (new URL("your url here")).openConnection(); 
       // read stream or whatever data you want 
       InputStream stream = c.getInputStream(); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
       //close your connection & wipe input stream here. 
      } 
     } 
    } 

现在这里是我们如何能够把这个线索:

private Thread downloadThread = new MyThread(); 
downloadThread.start(); 

在任何时候,你也可以检查,如果你的线程是通过使用运行或不下面的代码:

if (downloadThread != null && downloadThread.isAlive()) { 
    // do something when thread is alive here 
} 
相关问题