[英]Getting too many file descriptor open, in java application while performing file operation
[英]Application not responding while performing a read/write operation on socket too frequently
在我的應用程序中,我有12位的字節數組,用於讀取狀態。 寫完這個數組后,我得到了不同按鈕的狀態。 基於此響應,我將我的按鈕設置為ON | OFF。 我反復執行此任務。如果我將此間隔時間設置得太短(即100毫秒)並且過於頻繁地按下這些按鈕,則我的應用程序將停止響應。
這是代碼片段。
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
getSharedSettings();
fanDimmer1=(ToggleButton)findViewById(R.id.button_fan1);
fanDimmer2=(ToggleButton)findViewById(R.id.button_fan2);
dimmerLight1=(ToggleButton)findViewById(R.id.button_light1);
dimmerLight2=(ToggleButton)findViewById(R.id.button_light2);
fanDimmer1.setOnClickListener(this);
fanDimmer2.setOnClickListener(this);
dimmerLight1.setOnClickListener(this);
dimmerLight2.setOnClickListener(this);
if(ip.equals("") || port.equals(""))
{
new AlertDialog.Builder(MainActivity.this)
.setTitle("Warning !")
.setMessage("Please set IP and PORT first")
.setIcon(android.R.drawable.ic_dialog_alert)
.setNeutralButton("ok", null)
.show();
}
else
{
new Thread(new Runnable()
{
@Override
public void run()
{
Log.v(TAG, "openconnection");
openConnection();
}
}).start();
m_handler = new Handler();
startRepeatingTask();
}
}
public void openConnection()
{
// TODO Auto-generated method stub
try
{
s = new Socket(ip, Integer.parseInt(port));
i = s.getInputStream();
iD = new DataInputStream(i);
o = s.getOutputStream();
oD = new DataOutputStream(o);
Log.v(TAG, "openconnection 2");
}
catch (UnknownHostException e) {
// TODO: handle exception
Log.v("UnknowHostException :::::", "In Catch Block");
e.printStackTrace();
}
catch (IOException e) {
// TODO: handle exception
Log.v("IOException :::::", "In Catch Block");
e.printStackTrace();
}
}
Runnable m_statusChecker = new Runnable()
{
@Override
public void run()
{
updateStatus();
m_handler.postDelayed(m_statusChecker,100);
}
private void updateStatus()
{
// TODO Auto-generated method stub
Log.v("test", "1");
try {
byte[] data1 = new byte[1024], packet1 =
{
(byte) 0x00,(byte) 0x00,(byte) 0x00,
(byte) 0x00,(byte) 0x00,(byte) 0x06,
(byte) 0x01,(byte) 0x01,(byte) 0x00,
(byte) 0x00,(byte) 0x00,(byte) 0x19
};
o.write(packet1);
i.read(data1, 0, 1024);
byte_to_hex = ConversionMethods.bytesToHex(data1).substring(18, 26);
char[] arr = byte_to_hex.toCharArray();
for (int i = 0; i < arr.length - 1; i += 2)
{
char temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
swapped_result=new String(arr);
result = ConversionMethods.hexStringToNBitBinary(swapped_result, 32);
int counter = 0;
for( int i=0; i<result.length(); i++ )
{
if( result.charAt(i) == '1' )
{
counter++;
}
}
status=Integer.toString(counter);
txt_status.setText(status);
Log.v(TAG, "status is ::"+status);
char[] c=result.toCharArray();
int count=0;
for (int i=0;i<result.length();i++)
{
count++;
char j=c[i];
//Log.v(TAG, count+"::"+j);
if(count==1)
toggleButton=dimmerLight1;
else if(count==2)
toggleButton=fanDimmer2;
else if(count==3)
toggleButton=fanDimmer1;
else if(count==4)
Log.v(TAG, "Count 4 is 0");
if(j=='1')
toggleButton.setChecked(true);
else
toggleButton.setChecked(false);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
void startRepeatingTask() {
m_statusChecker.run();
}
void stopRepeatingTask() {
m_handler.removeCallbacks(m_statusChecker);
}
在按鈕上單擊我正在這樣做:
@Override
public void onClick(View v)
{
if(v.equals(fanDimmer1))
{
if (fanDimmer1.isChecked())
{
Toast.makeText(MainActivity.this, "Fan 1 is ON", Toast.LENGTH_SHORT).show();
setByteArray((byte) 0x01, (byte) 0xff);
} else
{
Toast.makeText(MainActivity.this, "Fan 1 is OFF", Toast.LENGTH_SHORT).show();
setByteArray((byte) 0x01, (byte) 0x00);
}
}
}
這是setByteArray()方法,我有24種這種類型的按鈕。
任何意見和建議,將不勝感激。
謝謝
您正在從主線程調用startRepeatingTask()
:
void startRepeatingTask() {
m_statusChecker.run();
}
這意味着您的statusChecker也將在主線程中運行。
要做的第一件事是更新updateStatus方法的代碼,並使用mHandler
將ui-update代碼僅發布到主UI線程
接下來,您必須在另一個線程中運行statusChecker
為此,您(至少)有兩個選擇:
[復雜的方法]執行自己的線程管理,並在startRepeatingTask中編寫類似的內容
void startRepeatingTask() { new Thread(m_statusChecker).start(); }
調整停止方法(即使用監視器,無限循環和睡眠)
[聰明的方法]從Android API看一下Timer和TimerTask (以及this ),並使用它們來實現所需的功能。
編輯
專注於此代碼:
for (int i=0;i<result.length();i++)
{
count++;
char j=c[i];
//Log.v(TAG, count+"::"+j);
if(count==1)
toggleButton=dimmerLight1;
else if(count==2)
toggleButton=fanDimmer2;
else if(count==3)
toggleButton=fanDimmer1;
else if(count==4)
Log.v(TAG, "Count 4 is 0");
if(j=='1')
toggleButton.setChecked(true);
else
toggleButton.setChecked(false);
}
此循環的效果將是:
我很確定這不是您所需要的。 (除非result.size()始終為3,但在任何其他情況下:此代碼都會產生怪異的東西)
您可以執行以下操作:
//assuming buttons is a ToggleButton[32] populated with all your buttons in the correct order
for (int i=0;i<result.length();i++)
{
buttons[i].setChecked(c[i]=='1');
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.