繁体   English   中英

最终局部变量无法分配,因为它是在封闭类型java中定义的

[英]The final local variable cannot be assigned, since it is defined in an enclosing type java

我已经创建了一个实现了`GetChildList``接口的childList类,如下所示:

    package com.example.hakslogin;

import java.util.ArrayList;
import java.util.List;
import com.example.hakslogin.GetChildList;
import com.example.hakslogin.HandleJSON;

public class childList implements GetChildList
{
    private HandleJSON obj;
    public String urlString = "http://192.168.x.xx:xxxx/getdb";
    public void callFetchJSONChild(){
        HandleJSON obj = new HandleJSON(urlString);
        List<String> list = obj.fetchJSONChild(this);
   }
    @Override
    public void onGetChildList(List<String> list) {
        // here your work with list
        //List<String> child = new ArrayList<String>();
        obj = new HandleJSON(urlString);
        list = obj.fetchJSONChild(this);
    }
}

我有一个如下的方法fetchJSONChild()

List<String> child = new ArrayList<String>();
           public void fetchJSONChild(final GetChildList callBack){
                final String[] str =  new String[3];
               // final List<String> child = new ArrayList<String>();
            Thread thread = new Thread(new Runnable(){
               @Override
               public void run() {
               try {
                  URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
                  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                  conn.setReadTimeout(30000 /* milliseconds */);
                  conn.setConnectTimeout(50000 /* milliseconds */);
                  conn.setRequestMethod("GET");
                  conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
                  conn.setRequestProperty("Content-Type", "application/json");
                  conn.setDoInput(true);
                  conn.setUseCaches (false);
                  // Starts the query
                  if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13)
                  {
                   conn.setRequestProperty("Connection", "close"); 
                  }
                  conn.connect();

                  System.out.println("Before url.openStream()");
               InputStream stream = conn.getInputStream();//.openStream();
               System.out.println("After url.openStream()");
            String data = convertStreamToString(stream);
            // for example String data = "1,2,3";
            child.addAll(Arrays.asList(data.split(",")));

            readAndParseJSON(data);
            stream.close();
            callBack.onGetChildList(child);
               } catch (Exception e) {
                  e.printStackTrace();
               }
               }

             thread.start();

         }

在此方法中,线程正在运行,我想将分割后的字符串数据放入到活动中的list<string> ,以下是我称为ChildActivity活动:

package com.example.hakslogin;

import java.util.ArrayList;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.example.hakslogin.GetChildList;

public class ChildActivity extends ActionBarActivity {

    private ListView lv_child;
    List<String> child = new ArrayList<String>();
    Button btn_home;
    Button btn_add;
    private HandleJSON obj;
    public String urlString = "http://192.168.x.xx:xxxx/getdb";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);


        obj = new HandleJSON(urlString);
        obj.fetchJSONChild(null);
        lv_child = (ListView)findViewById(R.id.lv_child); 
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, child);
        lv_child.setAdapter(adapter);
}

public void onGetChildList(List<String> list) {
   //this method will be called after thread in fetchJSONChild ended
   child = list;
   lv_child = (ListView)findViewById(R.id.lv_child); 
   String arr[]=child.toArray(new String[list.size()]);
   String[] Temp= new String[2];
          Temp[0] = arr[2].toString();
          array.add(Temp[0].split(":")[1]);
          String s = Temp[0].toString();
   ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,array);
   lv_child.setAdapter(adapter);

}

}

当我从ChildActivity onGetChildList方法上的list填充listview时,出现异常android.view.viewrootimpl$calledfromwrongthreadexception

请建议我,我应该等待的答复。

谢谢

final List<String> child = new ArrayList<String>();

并更换

child = new ArrayList<String>(Arrays.asList(data1.split(",")));

child.addAll(Arrays.asList(data1.split(","))

1) final表示您永远不会更改此变量。 因此,您应该使用全局变量或将其初始化为空数组,然后将其填充。 无论如何,你有奇怪的算法...

2)您启动线程。 因此,其中的所有代码都是异步的。 并且您的手术还return child; (在您的情况下)始终返回null。

因此,我建议您对线程使用回调,因为它是异步操作...

好的,这就是它的外观:

1)声明界面:

public interface GetChildList{
        public void onGetChildList(List<String> list);
}

2)在您的类(调用fetchJSONChild() )中实现它:

import com.example.hakslogin.GetChildList;

public class ChildActivity extends ActionBarActivity implements GetChildList {

    Button btn_home;
    Button btn_add;
    private HandleJSON obj;
    public String urlString = "http://192.168.x.xx:xxxx/getdb";

    List<String> child = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);


        obj = new HandleJSON(urlString);
        obj.fetchJSONChild(null);
        lv_child = (ListView)findViewById(R.id.lv_child); 
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, child);
        lv_child.setAdapter(adapter);
    }
    Handler mHandler = new Handler() {
      public void handleMessage(android.os.Message msg) {
        lv_child = (ListView)findViewById(R.id.lv_child); 
         String arr[]=child.toArray(new String[list.size()]);
         String[] Temp= new String[2];
         Temp[0] = arr[2].toString();
         array.add(Temp[0].split(":")[1]);
         String s = Temp[0].toString();
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,array);
         lv_child.setAdapter(adapter);
      };
   };



    @Override
    public void onGetChildList(List<String> list) {
       //this method will be called after thread in fetchJSONChild ended
       child = list;
       mHandler.sendEmptyMessage(0);

    }
}

3)您的fetchJSONChild将如下所示:

public void fetchJSONChild(final GetChildList callBack){

        final List<String> child = new ArrayList<String>();
        Thread thread = new Thread(new Runnable(){

            @Override
            public void run() {

                try {

                    URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setReadTimeout(30000 /* milliseconds */);
                    conn.setConnectTimeout(50000 /* milliseconds */);
                    conn.setRequestMethod("GET");
                    //conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
                    conn.setRequestProperty("Content-Type", "application/json");
                    conn.setDoInput(true);
                    //conn.setUseCaches (false);
                    // Starts the query
                    if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {

                        conn.setRequestProperty("Connection", "close"); 
                    }
                    conn.connect();

                    System.out.println("Before url.openStream()");
                    InputStream stream = conn.getInputStream();//.openStream();
                    System.out.println("After url.openStream()");
                    String data = convertStreamToString(stream);
                    // for examole data = "1,2,3";

                    child.addAll(Arrays.asList(data.split(","));
                    readAndParseJSON(data);
                    stream.close();

                    callBack.onGetChildList(child);
                } catch (Exception e) {

                    e.printStackTrace();
                }
            }
        });
        thread.start(); 
    }

4)在实现GetChildList类中调用fetchJSONChild(this)

5)线程结束工作后,它将调用onGetChildList ,您可以在其中处理数据。

这种花费时间并在后台线程中工作以不冻结屏幕的过程无法返回处理值。 因为,方法将在线程甚至开始之前完成执行! 您启动线程。 当结果在runOnUiThread中准备好时,您可以执行任何操作。 例如停止加载图标并向用户显示数据。 那个概念。

List<String> child;
public void fetchJSONChild(){
         //= new ArrayList<String>();
    Thread thread = new Thread(new Runnable(){
       @Override
       public void run() {
       try {
          URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
          HttpURLConnection conn = (HttpURLConnection) url.openConnection();
          conn.setReadTimeout(30000 /* milliseconds */);
          conn.setConnectTimeout(50000 /* milliseconds */);
          conn.setRequestMethod("GET");
          //conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
          conn.setRequestProperty("Content-Type", "application/json");
          conn.setDoInput(true);
          //conn.setUseCaches (false);
          // Starts the query
          if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13)
          {
           conn.setRequestProperty("Connection", "close"); 
          }
          conn.connect();

          System.out.println("Before url.openStream()");
       InputStream stream = conn.getInputStream();//.openStream();
       System.out.println("After url.openStream()");
    String data = convertStreamToString(stream);
    // for examole data = "1,2,3";

    child = new ArrayList<String>(Arrays.asList(data.split(","))); // <<<<---- data not data1!?
    readAndParseJSON(data);

    runOnUiThread(new Runnable() {
                public void run() {
                    // here you can update the ui with the child values.
                    for (int i=0;i<child.size();i++)
                         Log.e("Child", child.get(i));
                }
            });
       stream.close();

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

     thread.start();
 }

注意:如果活动类中的方法,则此解决方案效果很好。 如果不是,请说出来,以便我提供适当的解决方案。

删除child的final声明并使其成为全局变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM