[英]The final local variable cannot be assigned, since it is defined in an enclosing type java
I have created class childList
that implements an interface `GetChildList`` like below: 我已经创建了一个实现了`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);
}
}
I have a method fetchJSONChild()
like below: 我有一个如下的方法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();
}
And in this method thread is running and I want to get splitted string data that I put into the list<string>
into my activity and below is my activity that I called ChildActivity
: 在此方法中,线程正在运行,我想将分割后的字符串数据放入到活动中的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);
}
}
I am getting exception android.view.viewrootimpl$calledfromwrongthreadexception
when I populate listview
from list
on onGetChildList
method in my ChildActivity
. 当我从ChildActivity
onGetChildList
方法上的list
填充listview
时,出现异常android.view.viewrootimpl$calledfromwrongthreadexception
。
Kindly suggest me, what I should waiting for reply. 请建议我,我应该等待的答复。
Thanks 谢谢
final List<String> child = new ArrayList<String>();
and replace 并更换
child = new ArrayList<String>(Arrays.asList(data1.split(",")));
with 与
child.addAll(Arrays.asList(data1.split(","))
1) final
is mean that you will never change this variable. 1) final
表示您永远不会更改此变量。 So you should use global variable or init it whith empty array and then fill it. 因此,您应该使用全局变量或将其初始化为空数组,然后将其填充。 Anyway, you have strange algorithm... 无论如何,你有奇怪的算法...
2) You start Thread. 2)您启动线程。 So all code inside it will be asynchronously. 因此,其中的所有代码都是异步的。 And your operation return child;
并且您的手术还return child;
(in your case) always return null. (在您的情况下)始终返回null。
So, i recommend you to use callback for your thread cause it's assync operation... 因此,我建议您对线程使用回调,因为它是异步操作...
Ok, thats how it's should look: 好的,这就是它的外观:
1) Declare interface: 1)声明界面:
public interface GetChildList{
public void onGetChildList(List<String> list);
}
2) In you class (where you call fetchJSONChild()
) implement it: 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) Your fetchJSONChild
will something like this: 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) in your class where you implemented GetChildList
call fetchJSONChild(this)
4)在实现GetChildList
类中调用fetchJSONChild(this)
5) After thread end working it will call onGetChildList
where you can process you data. 5)线程结束工作后,它将调用onGetChildList
,您可以在其中处理数据。
This type of process which take time and work in background thread to not freeze the screen can't return the processing value. 这种花费时间并在后台线程中工作以不冻结屏幕的过程无法返回处理值。 because, method will finish executing before the thread even start!! 因为,方法将在线程甚至开始之前完成执行! you start the thread. 您启动线程。 and when the result is ready in runOnUiThread you do whatever you want. 当结果在runOnUiThread中准备好时,您可以执行任何操作。 like stop the loading icon and show data to user. 例如停止加载图标并向用户显示数据。 that the concept. 那个概念。
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();
}
Note: this solution works perfectly if the method in the activity class. 注意:如果活动类中的方法,则此解决方案效果很好。 if not, please say so I can provide a proper solution. 如果不是,请说出来,以便我提供适当的解决方案。
删除child的final
声明并使其成为全局变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.