0

동일한 WebView에서 loadData() 할 많은 AsyncTasks 실행하려고합니다. 예를 들어, "1", "2", "3"및 내용이 "abc"인 WebView가있는 3 개의 스레드가있는 스레드가 3 개 있습니다. (아래 코드와 같습니다)여러 AsyncTasks 동일한 WebView로드

3 개의 작업이 끝나면 WebView에 콘텐츠 "abcOneTwoThree"가 있어야합니다. 이 코드는 3 개의 스레드가 언제든지 WebView에 내용을 추가하므로 "abcTwoOneThree"또는 "abcTwoThreeOne"등이 될 수 있습니다.

많은 동시성 기사를 읽었지만 여전히 이해할 수 없습니다. 이것을 구현하는 방법. 이것은 내 코드입니다. 그냥 "abcThree"를 출력합니다.

public class UsingSameWebViewActivity extends Activity implements OnClickListener { 
    private Button button1; 
    private WebView webView; 
    private String result; 

    @Override 
    public void onCreate(final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     button1 = (Button)findViewById(R.id.button1); 
     button1.setOnClickListener(this); 
     webView = (WebView)findViewById(R.id.webView1); 
     result = "abc"; 
    } 

    @Override 
    public void onClick(final View v) { 
     final String[] contents = {"One", "Two", "Three"}; 
     for(int i = 0; i < 3; ++i) { 
      final FooTask task = new FooTask(webView, result); 
      task.execute(contents[i]); 
     } 
    } 

    private class FooTask extends AsyncTask<String, Void, String> { 
     private final WebView resultView; 
     private String result; 

     // This is what I try to make it work right. 
     private synchronized String getResult() { 
      return result; 
     } 

     public FooTask(final WebView resultView, final String result) { 
      this.resultView = resultView; 
      this.result = result; 
     } 

     @Override 
     protected String doInBackground(final String... params) { 
     // Do a long time work randomly then returns a string. 
      return params[0]; 
     } 

     @Override 
     protected void onPostExecute(final String content) { 
      result = getResult() + content; 
      resultView.loadData(result, "text/html", "utf-8"); 
     } 
    } 
} 

답변

1

비동기 작업 클래스에서 private String result; 줄을 제거하십시오.

+0

그것은 작동하지만, FooTask가 내부 클래스가 아니면 어떻게됩니까? 내 코드에서와 같이 FooTask에 '결과'를 전달해야합니까? – Emerald214

+0

그런 다음'result'를'async task'의'정적'멤버로 만듭니다. 문제는 근본적으로 빈 문자열로 내용을 추가하고 정적으로 만들면 효과가 있습니다. –

+0

... 정적을 사용하는 것은 아주 이상합니다. : | 그것이 좋은 연습인지 모른다. – Emerald214

1

바로이 라인을 AsynTaskpostExecute()에서 task.execute(contents[i]); 를 추가하고 [내가] 클래스 변수로 .. 두 번 task.execute(contents[i]); 호출이 당신이 "일을하고 싶어하기 때문에 내용을 ... 여기에서 할 일이 많이 아무것도 없다 "및"two "

+0

아니요, 각 작업에서 결과 변수에 내용을 추가하고 즉시 WebView에로드하려고합니다. 즉 작업 A가 결과에 '1'을 추가하고 작업 B가 결과에 '2'를 추가하면 ... 순서는 중요하지 않습니다. 귀하의 답을 오해 한 경우 몇 가지 코드를 추가하십시오. – Emerald214

+0

그게 무슨 말을하려고하는지 .. 당신은 postExecute 여러 번 안으로 asyncTask를 호출 할 수 있습니다 .. 그리고 아마 당신의 목적을 위해 일할 것입니다 .. – ngesh

1

onPostExecute()에서 결과를 어딘가에 "반환"하고 싶습니다. 즉, FooTask은 결과를 넣을 자리가 필요합니다. 가능성있는 후보는 호출자가 결과를 배치하기 위해 호출 할 수있는 일종의 메소드 일 것입니다. 메서드를 synchronized으로 지정해야합니다. 그렇지 않으면 반환 값 중 일부가 손실 될 수 있습니다.

또는 FooTaskHandler으로 보내면 Message을 보낼 수 있습니다. 이 경우 모든 Message이 메인/UI 스레드로 보내 지므로 동기화 할 필요가 없습니다. 메인/UI 스레드가이를 순차적으로 처리합니다.

관련 문제