4

In a subclass of WebView, I have this in an overridden method of getTitle():

      @Override
      public String getTitle() {
        Activity a = getVoTts().getActivity();
        a.runOnUiThread(new Runnable() {
            public void run() { 
                String tit = VoWebView.super.getTitle();
            }
        });


       String title = tit;  // this is what I WANT to do, it won't compile of course
       ...
       ...
      }

But the String tit is closed in an anonymous Runnable class and thus of course cannot be accessed down the method.

Is there any technique or "trick" that would allow me to pass a value obtained in an anonymous Runnable class to statements down the lines (in the same method) or assign it to a data member?

4

4 回答 4

5

One way would be by declaring an instance field and using it across the whole class. For example:

private String someText;

// ...

@Override
public String getTitle()
{
    Activity a = getVoTts().getActivity();
    a.runOnUiThread(new Runnable()
    {
        public void run()
        {  
            someText = VoWebView.super.getTitle();
        }
    });
}

EDIT:

Regarding the reason of why you have to declare a local variable as final (or in other word, compile time constant):

Imagine the following is valid in Java:

@Override
public String getTitle()
{
    Foo f = new Foo();

    Button b = getButtonReference();
    b.setOnClickListener(new OnClickListener()
    {
        public void onClick(View v)
        {  
            Boo o = f.someMethod();
        }
    });

    f = null;
}

At f = null, the foo object will be eligible for garbage-collected. So if you click the button, it's too late for the VM to invoke someMethod() on the foo object, since it's garbage-collected!

于 2013-01-01T21:03:39.120 回答
1

Why don't you declare a global variable:

 private String title;

  @Override
  public String getTitle() {
    Activity a = getVoTts().getActivity();
    a.runOnUiThread(new Runnable() {
        public void run() { 
            title = VoWebView.super.getTitle();
        }
    });
  }
于 2013-01-01T21:05:34.853 回答
1

You can use FutureTask as follows:

FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
    @Override
    public String call() throws Exception {
        // Compute your string
    }
});

runOnUiThread(task);
String title = task.get();
于 2014-01-03T14:28:34.370 回答
0

Update

According to a comment, .runOnUiThread() runs its runnable asynchronously, which means the task may or may not have run by the time we get to the "statements down the lines". Then it is impossible to get the results to those statements in the rest of the method (and none of the solutions here will help you with that).

于 2013-01-02T10:21:19.883 回答