2016-04-15 11 views
2

私は2つのネットワーク計算を行うThreadを持っています。 私は私のアプリを実行し、Thread私の第二の開始後に私が手:すべてのスレッドを一時停止しました:スレッドを使用したms警告 -

Background sticky concurrent mark sweep GC freed 246745(21MB) AllocSpace objects, 169(6MB) LOS objects, 33% free, 31MB/47MB, paused 1.972ms total 127.267ms警告:続い

Suspending all threads took: ms 警告を。

時には、2つの警告が表示されることがあります。アプリを終了させることを決定するまで、2つの警告が多く表示されることがあります。この時点で、それはメインのThreadを実行しているだけで、基本的に何もしません。

MainActivity.java

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

    // Getting html page through a thread 
    this.getHtmlPageThread = new GetHtmlPageThread(URL_STRING); 
    this.getHtmlPageThread.start(); 

    // The thread that will search the web for data 
    this.getDataFromTheWebThread = new GetDataFromTheWebThread(); 

    // Search button click listener 
    searchButton.setOnClickListener(new View.OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      // Get the searched lyrics 
      searchedLyrics = inputEditText.getText().toString(); 

      informUserAboutConnectionToTheNet(); 

      // Starting to search the web for data through a thread 
      getDataFromTheWebThread.start(); 

      if (!getDataFromTheWebThread.isAlive()) 
      { 
       printMap(MainActivity.matchResultMap); 
      } 
     } 
    }); // End of search button click listener 

    printMap(MainActivity.matchResultMap); 

} // End of onCreate() method 

protected void onStart() 
{ 
    super.onStart(); 

    if (!this.isParseSucceeded()) // Connection to net failed 
    { 
     if (!getHtmlPageThread.isAlive()) // If the thread is not alive, start it. 
     { 
      getHtmlPageThread.start(); // Try to connect again 
      this.informUserAboutConnectionToTheNet(); 
     } 
    } 
    if (!this.isParseSucceeded()) 
    { 
     super.onStart(); // Call onStart() method 
    } 

} // End of onStart() method 

GetHtmlPageThread.java:ここでは、関連するコードがある

public class GetHtmlPageThread extends Thread 
{ 
    private String url; 

    public GetHtmlPageThread(String url) 
    { 
     this.url = url; 
    } 

    @Override 
    public void run() 
    { 
     try 
     { 
      MainActivity.htmlPage.setHtmlDocument(this.getParsedDocument(this.url)); 
      if (MainActivity.htmlPage.getHtmlDocument() != null) 
      { 
       MainActivity.parsedSucceeded = true; // Parsed succeeded 
      } 
      else 
      { 
       MainActivity.parsedSucceeded = false; // Parsed failed 
      } 
      Thread.sleep(100); 
     } 
     catch (InterruptedException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Returns the document object of the url parameter. 
    * If the connection is failed , return null. 
    * 
    * @param url Url to parse 
    * @return The document of the url. 
    * 
    */ 
    public Document getParsedDocument(String url) 
    { 
     try 
     { 
      return Jsoup.connect(url).get(); 
     } 
     catch (IOException e) // On error 
     { 
      e.printStackTrace(); 
     } 

     return null; // Failed to connect to the url 
    } 

} 

GetDataFromTheWeb.java

public class GetDataFromTheWebThread extends Thread 
{ 
    public static boolean isFinished = false; // False - the thread is still running. True - the thread is dead 

    @Override 
    public void run() 
    { 
     GetDataFromTheWebThread.isFinished = false; 
     try 
     { 
      this.getLyricsPlanetDotComResults(MainActivity.searchedLyrics); // Method for internet computations 
      Thread.sleep(100); 
     } 
     catch (InterruptedException e) 
     { 
      e.printStackTrace(); 
     } 
     GetDataFromTheWebThread.isFinished = true; 
    } 
    ... 
} 

第2のThreadの基本的にthis.getLyricsPlanetDotComResults(MainActivity.searchedLyrics);メソッドは、インターネットの仕事と計算の多くを一般的に行っています。厳密には正味のものより多くの計算。

2番目のThreadが「ビジー」なので、警告が表示されたと思いますか?あるいは、onCreate()メソッドとonStart()メソッドを使用したアクティビティライフサイクルの実装は間違っていますか?

言うまでもなく、アプリをデバッグして2番目のThreadを突き抜けて動作しても、出力が得られません。完璧にです。もう一度、それは私のActivityの実装で何かになるはずです。

答えて

8

最初の行は、ガベージコレクタ(GC)が、作業の一部(変数の再配置など)を中断する必要があり、時間がかかると判断したということです。通常はそこに数字があります。

2行目は、コレクションの結果です。それはかなりの量のメモリを解放し、今ではヒープの1/3が解放されています。それはあなたのアプリが2msの間一時停止され、合計で127msがゴミを収集するのに費やされました。

GC自体は悪くありません。しかし、あなたがいつもそれをやっているなら、あなたはたくさんの記憶が必要なものをやっているのか、あるいは非効率的に何かをやっているのです。特にJSoupのような重い文字列解析は、携帯電話のような小さなメモリデバイスで素早くクリーンアップが必要な小さなオブジェクト(主に文字列)をたくさん作成することがあるため、ここでは驚くことではありません。

基本的に、これはGCからパフォーマンスの不具合を取得している場合、またはある時点でOOMに行く場合にのみ問題になります。それらのいずれも起こっていなければ、私はまだこれについて心配しないでしょう。

+0

わかりました。しかし、私は 'Thread'が私が望むものを正確にやっているのを見ることができます(**' MainActivity.java'のグローバル変数を更新するために)、いつ私がそれにアクセスできるか分かりません( 'スレッド 'が行われているのは仕事です)と方法(私はそれのような' Loop'が必要なので - 'while(!myThread、isAlive()){//私の仕事をしてください} '、しかしそれは良い実装ですか?また、 'Thread'を' HandlerThread'に変更することについては、http://developer.android.com/intl/zh-cn/reference/android/os/HandlerThread.htmlを参照してください。どう思いますか?ありがとう。 – God

+0

スレッドが完了したタイミングを知る必要がある場合は、コールバックを使用します(UIスレッドで通知が必要な場合は、UIスレッドでハンドラからコールバックを行う必要があります)。 HandlerThreadは、応答しなければならない一連のイベントを送信するスレッドのためのものです。 –

+0

http://stackoverflow.com/questions/19366301/run-callback-on-main-threadここのように? – God

関連する問題