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

无法分配最终的局部变量,因为它是在封闭类型java中定义的,java,android,multithreading,list,Java,Android,Multithreading,List,我创建了类childList,它实现了一个接口“GetChildList”,如下所示: 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

我创建了类childList,它实现了一个接口“GetChildList”,如下所示:

    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);
    }
}
在这个方法中,线程正在运行,我想得到被拆分的字符串数据,我把这些数据放到我的活动列表中,下面是我的活动,我称之为ChildActivity:

当我从ChildActivity中onGetChildList方法上的列表填充listview时,我收到了异常android.view.viewrootimpl$CalledFromErrorThreadException

请建议我,我应该等待什么答复

谢谢

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

1 final意味着您永远不会更改此变量。所以您应该使用全局变量或初始化它,然后填充空数组。不管怎样,你有一个奇怪的算法

final List<String> child = new ArrayList<String>();
2.你开始写这篇文章。所以它里面的所有代码都是异步的。和你的手术返回孩子;在您的情况下,始终返回null

所以,我建议您对线程使用回调,因为这是一个异步操作

好的,它应该是这样的:

1.声明接口:

public interface GetChildList{
        public void onGetChildList(List<String> list);
}
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调用fetchJSONChildthis的类中


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

这种类型的处理需要时间并在后台线程中工作,以不冻结屏幕,因此无法返回处理值。因为,方法将在线程开始之前完成执行!!你开始发帖。当结果在RunUnuithRead中准备好时,您可以做任何您想做的事情。例如停止加载图标并向用户显示数据。这就是概念

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();
 }

注意:如果activity类中的方法。如果没有,请说明我可以提供适当的解决方案。

将其声明为全局变量是的,我将列表声明为全局变量,错误被删除,但当我调试应用程序并检查变量值时,拆分后,它不会向我显示任何类似于1、2、3的值。这是Sufitruf下面提到的问题的第二部分-由于线程是异步的,在退出方法后,数组仍然为空。否,然后他不能在匿名类中使用它。对于记录,一旦变量声明为最终值,您就不能更改它的值。不确定为什么会被否决-它应该修复报告的问题-尽管返回时列表仍然为空。如何检查child2是否有值,例如,1,2,3它应该有值。拆分字符串后数据,我有问题了。修好它。waitI已经运行了您的代码,但子项仍然为空,我想返回列表子项;并且您的代码段不返回List child;。此方法是否存在于activity类中?此类型的进程需要时间并在后台线程中工作才能不冻结屏幕,因此无法返回处理值。因为,方法将在线程开始之前完成执行!!你开始发帖。当结果在RunUnuithRead中准备好时,您可以做任何您想做的事情。例如停止加载图标并向用户显示数据。您应该在的导入部分导入GetChildListfile@user3514596您不应该在onGetChildList中调用fetchJSONChildthis。onGetChildList方法将在fetchJSONChild之后调用ended@user3514596导入yout_package.GetChildList@user3514596您应该将其导入HandleJSON文件中,我已经编辑了我的帖子,并尝试完成您所说的内容,但仍然出现错误,我不知道从何处获取列表数据,即我称之为child的1,2,3。我仍然感到困惑
child.addAll(Arrays.asList(data1.split(","))
public interface GetChildList{
        public void onGetChildList(List<String> list);
}
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);

    }
}
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(); 
    }
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();
 }