java - 最终局部变量不能被赋值,因为它是在封闭类型 java 中定义的

标签 java android multithreading list

我创建了类childList,它实现了一个接口(interface)`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);
    }
}

我有一个如下所示的 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> 到我的 Activity 中的分割字符串数据,下面是我称为 ChildActivity 的 Activity :

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

}

}

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

请建议我,我应该等待回复。

谢谢

最佳答案

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

2) 您启动线程。所以里面的所有代码都是异步的。并且您的操作 return child; (在您的情况下)始终返回 null。

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

好的,这就是它应该看起来的样子:

1)声明接口(interface):

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,您可以在其中处理数据。

关于java - 最终局部变量不能被赋值,因为它是在封闭类型 java 中定义的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27146259/

相关文章:

android - HttpClient 在 Android 5.0 Lollipop 中失败并显示 Handshake Failed

java - Android Phonegap fatal error

java - 在测试和生产代码中获取一致的资源文件夹路径

java - 我的启动中的某些内容导致应用程序崩溃。如果有人能提供帮助,我将不胜感激

java - 如何根据网络服务器上的状态自动更新应用程序变量

javascript - Node ,如何使同步代码超时?

c# - 确定两个 BackGroundWorker 字符串是否返回 true

java - 基于点的曲线变换。 Android 中的贝塞尔曲线变换

android - 两个不同的 AsyncTasks 同时执行

java - Spring Rest Web 请求范围